* Indicate that a predicate lock on the given target is held by the * specified transaction. Has no effect if the lock is already held. * * This updates the lock table and the sxact's lock list, and creates * the lock target if necessary, but does *not* do anything related to * granularity promotion or the local lock table. See * PredicateLockAcquire for that. */
| 2442 | * PredicateLockAcquire for that. |
| 2443 | */ |
| 2444 | static void |
| 2445 | CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag, |
| 2446 | uint32 targettaghash, |
| 2447 | SERIALIZABLEXACT *sxact) |
| 2448 | { |
| 2449 | PREDICATELOCKTARGET *target; |
| 2450 | PREDICATELOCKTAG locktag; |
| 2451 | PREDICATELOCK *lock; |
| 2452 | LWLock *partitionLock; |
| 2453 | bool found; |
| 2454 | |
| 2455 | partitionLock = PredicateLockHashPartitionLock(targettaghash); |
| 2456 | |
| 2457 | LWLockAcquire(SerializablePredicateListLock, LW_SHARED); |
| 2458 | if (IsInParallelMode()) |
| 2459 | LWLockAcquire(&sxact->perXactPredicateListLock, LW_EXCLUSIVE); |
| 2460 | LWLockAcquire(partitionLock, LW_EXCLUSIVE); |
| 2461 | |
| 2462 | /* Make sure that the target is represented. */ |
| 2463 | target = (PREDICATELOCKTARGET *) |
| 2464 | hash_search_with_hash_value(PredicateLockTargetHash, |
| 2465 | targettag, targettaghash, |
| 2466 | HASH_ENTER_NULL, &found); |
| 2467 | if (!target) |
| 2468 | ereport(ERROR, |
| 2469 | (errcode(ERRCODE_OUT_OF_MEMORY), |
| 2470 | errmsg("out of shared memory"), |
| 2471 | errhint("You might need to increase max_pred_locks_per_transaction."))); |
| 2472 | if (!found) |
| 2473 | SHMQueueInit(&(target->predicateLocks)); |
| 2474 | |
| 2475 | /* We've got the sxact and target, make sure they're joined. */ |
| 2476 | locktag.myTarget = target; |
| 2477 | locktag.myXact = sxact; |
| 2478 | lock = (PREDICATELOCK *) |
| 2479 | hash_search_with_hash_value(PredicateLockHash, &locktag, |
| 2480 | PredicateLockHashCodeFromTargetHashCode(&locktag, targettaghash), |
| 2481 | HASH_ENTER_NULL, &found); |
| 2482 | if (!lock) |
| 2483 | ereport(ERROR, |
| 2484 | (errcode(ERRCODE_OUT_OF_MEMORY), |
| 2485 | errmsg("out of shared memory"), |
| 2486 | errhint("You might need to increase max_pred_locks_per_transaction."))); |
| 2487 | |
| 2488 | if (!found) |
| 2489 | { |
| 2490 | SHMQueueInsertBefore(&(target->predicateLocks), &(lock->targetLink)); |
| 2491 | SHMQueueInsertBefore(&(sxact->predicateLocks), |
| 2492 | &(lock->xactLink)); |
| 2493 | lock->commitSeqNo = InvalidSerCommitSeqNo; |
| 2494 | } |
| 2495 | |
| 2496 | LWLockRelease(partitionLock); |
| 2497 | if (IsInParallelMode()) |
| 2498 | LWLockRelease(&sxact->perXactPredicateListLock); |
| 2499 | LWLockRelease(SerializablePredicateListLock); |
| 2500 | } |
| 2501 |
no test coverage detected