• Tom Lane's avatar
    Fix dangling pointer in EvalPlanQual machinery. · 01d9676a
    Tom Lane authored
    EvalPlanQualStart() supposed that it could re-use the relsubs_rowmark
    and relsubs_done arrays from a prior instantiation.  But since they are
    allocated in the es_query_cxt of the recheckestate, that's just wrong;
    EvalPlanQualEnd() will blow away that storage.  Therefore we were using
    storage that could have been reallocated to something else, causing all
    sorts of havoc.
    
    I think this was modeled on the old code's handling of es_epqTupleSlot,
    but since the code was anyway clearing the arrays at re-use, there's
    clearly no expectation of importing any outside state.  So it's just
    a dubious savings of a couple of pallocs, which is negligible compared
    to setting up a new planstate tree.  Therefore, just allocate the
    arrays always.  (I moved the allocations slightly for readability.)
    
    In principle this bug could cause a problem whenever EPQ rechecks are
    needed in more than one target table of a ModifyTable plan node.
    In practice it seems not quite so easy to trigger as that; I couldn't
    readily duplicate a crash with a partitioned target table, for instance.
    That's probably down to incidental choices about when to free or
    reallocate stuff.  The added isolation test case does seem to reliably
    show an assertion failure, though.
    
    Per report from Oleksii Kliukin.  Back-patch to v12 where the bug was
    introduced (evidently by commit 3fb307bc4).
    
    Discussion: https://postgr.es/m/EEF05F66-2871-4786-992B-5F45C92FEE2E@hintbits.com
    01d9676a
eval-plan-qual.spec 14.1 KB