• Tom Lane's avatar
    Fix check for conflicting session- vs transaction-level locks. · 712ba6b8
    Tom Lane authored
    We have an implementation restriction that PREPARE TRANSACTION can't
    handle cases where both session-lifespan and transaction-lifespan locks
    are held on the same lockable object.  (That's because we'd otherwise
    need to acquire a new PROCLOCK entry during post-prepare cleanup, which
    is an operation that might fail.  The situation can only arise with odd
    usages of advisory locks, so removing the restriction is probably not
    worth the amount of effort it would take.)  AtPrepare_Locks attempted
    to enforce this, but its logic was many bricks shy of a load, because
    it only detected cases where the session and transaction locks had the
    same lockmode.  Locks of different modes on the same object would lead
    to the rather unhelpful message "PANIC: we seem to have dropped a bit
    somewhere".
    
    To fix, build a transient hashtable with one entry per locktag,
    not one per locktag + mode, and use that to detect conflicts.
    
    Per bug #17122 from Alexander Pyhalov.  This bug is ancient,
    so back-patch to all supported branches.
    
    Discussion: https://postgr.es/m/17122-04f3c32098a62233@postgresql.org
    712ba6b8
lock.c 140 KB