• Tom Lane's avatar
    Fix query-cancel handling in spgdoinsert(). · eb7a6b92
    Tom Lane authored
    Knowing that a buggy opclass could cause an infinite insertion loop,
    spgdoinsert() intended to allow its loop to be interrupted by query
    cancel.  However, that never actually worked, because in iterations
    after the first, we'd be holding buffer lock(s) which would cause
    InterruptHoldoffCount to be positive, preventing servicing of the
    interrupt.
    
    To fix, check if an interrupt is pending, and if so fall out of
    the insertion loop and service the interrupt after we've released
    the buffers.  If it was indeed a query cancel, that's the end of
    the matter.  If it was a non-canceling interrupt reason, make use
    of the existing provision to retry the whole insertion.  (This isn't
    as wasteful as it might seem, since any upper-level index tuples we
    already created should be usable in the next attempt.)
    
    While there's no known instance of such a bug in existing release
    branches, it still seems like a good idea to back-patch this to
    all supported branches, since the behavior is fairly nasty if a
    loop does happen --- not only is it uncancelable, but it will
    quickly consume memory to the point of an OOM failure.  In any
    case, this code is certainly not working as intended.
    
    Per report from Dilip Kumar.
    
    Discussion: https://postgr.es/m/CAFiTN-uxP_soPhVG840tRMQTBmtA_f_Y8N51G7DKYYqDh7XN-A@mail.gmail.com
    eb7a6b92
spgdoinsert.c 68 KB