Fix concurrent delete handling in MERGE ... WHEN NOT MATCHED BY SOURCE. When executing a WHEN NOT MATCHED BY SOURCE action in MERGE, if the tuple from the target table was concurrently deleted, the retry code would incorrectly execute a WHEN NOT MATCHED BY TARGET action for the row instead, giving incorrect results.
Fix in ExecMergeMatched() -- when handling a TM_Deleted failure status, it should only set *matched to false (telling the caller to execute any WHEN NOT MATCHED BY TARGET actions) if the failed action was a WHEN MATCHED action. For a failed WHEN NOT MATCHED BY SOURCE action, the source tuple did not exist, and the target tuple has just been deleted, so it should do nothing. Back-patch to v17, where support for WHEN NOT MATCHED BY SOURCE actions was introduced. Reported-by: Jeff Davis <[email protected]> Author: Tender Wang <[email protected]> Reviewed-by: Dean Rasheed <[email protected]> Discussion: https://postgr.es/m/[email protected] Backpatch-through: 17 Branch ------ REL_19_STABLE Details ------- https://git.postgresql.org/pg/commitdiff/fe1d5aeffda796710d97f917121670fd46ae82b1 Modified Files -------------- src/backend/executor/nodeModifyTable.c | 35 ++++-- src/test/isolation/expected/merge-delete.out | 158 +++++++++++++++++++++++++++ src/test/isolation/specs/merge-delete.spec | 37 +++++++ 3 files changed, 220 insertions(+), 10 deletions(-)
