* Search the relation 'rel' for tuple using the sequential scan. * * If a matching tuple is found, lock it with lockmode, fill the slot with its * contents, and return true. Return false otherwise. * * Note that this stops on the first matching tuple. * * This can obviously be quite slow on tables that have more than few rows. */
| 292 | * This can obviously be quite slow on tables that have more than few rows. |
| 293 | */ |
| 294 | bool |
| 295 | RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, |
| 296 | TupleTableSlot *searchslot, TupleTableSlot *outslot) |
| 297 | { |
| 298 | TupleTableSlot *scanslot; |
| 299 | TableScanDesc scan; |
| 300 | SnapshotData snap; |
| 301 | TypeCacheEntry **eq; |
| 302 | TransactionId xwait; |
| 303 | bool found; |
| 304 | TupleDesc desc PG_USED_FOR_ASSERTS_ONLY = RelationGetDescr(rel); |
| 305 | |
| 306 | Assert(equalTupleDescs(desc, outslot->tts_tupleDescriptor, true)); |
| 307 | |
| 308 | eq = palloc0(sizeof(*eq) * outslot->tts_tupleDescriptor->natts); |
| 309 | |
| 310 | /* Start a heap scan. */ |
| 311 | InitDirtySnapshot(snap); |
| 312 | scan = table_beginscan(rel, &snap, 0, NULL); |
| 313 | scanslot = table_slot_create(rel, NULL); |
| 314 | |
| 315 | retry: |
| 316 | found = false; |
| 317 | |
| 318 | table_rescan(scan, NULL); |
| 319 | |
| 320 | /* Try to find the tuple */ |
| 321 | while (table_scan_getnextslot(scan, ForwardScanDirection, scanslot)) |
| 322 | { |
| 323 | if (!tuples_equal(scanslot, searchslot, eq)) |
| 324 | continue; |
| 325 | |
| 326 | found = true; |
| 327 | ExecCopySlot(outslot, scanslot); |
| 328 | |
| 329 | xwait = TransactionIdIsValid(snap.xmin) ? |
| 330 | snap.xmin : snap.xmax; |
| 331 | |
| 332 | /* |
| 333 | * If the tuple is locked, wait for locking transaction to finish and |
| 334 | * retry. |
| 335 | */ |
| 336 | if (TransactionIdIsValid(xwait)) |
| 337 | { |
| 338 | XactLockTableWait(xwait, NULL, NULL, XLTW_None); |
| 339 | goto retry; |
| 340 | } |
| 341 | |
| 342 | /* Found our tuple and it's not locked */ |
| 343 | break; |
| 344 | } |
| 345 | |
| 346 | /* Found tuple, try to lock it in the lockmode. */ |
| 347 | if (found) |
| 348 | { |
| 349 | TM_FailureData tmfd; |
| 350 | TM_Result res; |
| 351 |
no test coverage detected