• Tom Lane's avatar
    Fix subtransaction cleanup after an outer-subtransaction portal fails. · c5454f99
    Tom Lane authored
    Formerly, we treated only portals created in the current subtransaction as
    having failed during subtransaction abort.  However, if the error occurred
    while running a portal created in an outer subtransaction (ie, a cursor
    declared before the last savepoint), that has to be considered broken too.
    
    To allow reliable detection of which ones those are, add a bookkeeping
    field to struct Portal that tracks the innermost subtransaction in which
    each portal has actually been executed.  (Without this, we'd end up
    failing portals containing functions that had called the subtransaction,
    thereby breaking plpgsql exception blocks completely.)
    
    In addition, when we fail an outer-subtransaction Portal, transfer its
    resources into the subtransaction's resource owner, so that they're
    released early in cleanup of the subxact.  This fixes a problem reported by
    Jim Nasby in which a function executed in an outer-subtransaction cursor
    could cause an Assert failure or crash by referencing a relation created
    within the inner subtransaction.
    
    The proximate cause of the Assert failure is that AtEOSubXact_RelationCache
    assumed it could blow away a relcache entry without first checking that the
    entry had zero refcount.  That was a bad idea on its own terms, so add such
    a check there, and to the similar coding in AtEOXact_RelationCache.  This
    provides an independent safety measure in case there are still ways to
    provoke the situation despite the Portal-level changes.
    
    This has been broken since subtransactions were invented, so back-patch
    to all supported branches.
    
    Tom Lane and Michael Paquier
    c5454f99
transactions.sql 10.2 KB