• Andres Freund's avatar
    Fix crash caused by EPQ happening with a before update trigger present. · d986d4e8
    Andres Freund authored
    When ExecBRUpdateTriggers()'s GetTupleForTrigger() follows an EPQ
    chain the former needs to run the result tuple through the junkfilter
    again, and update the slot containing the new version of the tuple to
    contain that new version. The input tuple may already be in the
    junkfilter's output slot, which used to be OK - we don't need the
    previous version anymore. Unfortunately ff11e7f4 started to use
    ExecCopySlot() to update newslot, and ExecCopySlot() doesn't support
    copying a slot into itself, leading to a slot in a corrupt
    state, which then can cause crashes or other symptoms.
    
    Fix this by skipping the ExecCopySlot() when copying into itself.
    
    While we could have easily made ExecCopySlot() handle that case, it
    seems better to add an assert forbidding doing so instead. As the goal
    of copying might be to make the contents of one slot independent from
    another, it seems failure prone to handle doing so silently.
    
    A follow-up commit will add tests for the obviously under-covered
    combination of EPQ and triggers. Done as a separate commit as it might
    make sense to backpatch them further than this bug.
    
    Also remove confusion with confusing variable names for slots in
    ExecBRDeleteTriggers() and ExecBRUpdateTriggers().
    
    Bug: #16036
    Reported-By: Антон Власов
    Author: Andres Freund
    Discussion: https://postgr.es/m/16036-28184c90d952fb7f@postgresql.org
    Backpatch: 12-, where ff11e7f4 was merged
    d986d4e8
tuptable.h 16.9 KB