From d17abaea8eda7e628d91550b0c059596c3d8b6e1 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 26 Aug 2025 11:38:41 -0400 Subject: [PATCH] Do CHECK_FOR_INTERRUPTS inside, not before, scanGetItem. The CHECK_FOR_INTERRUPTS call in gingetbitmap turns out to be inadequate to prevent a long uninterruptible loop, because we now know a case where looping occurs within scanGetItem. While the next patch will fix the bug that caused that, it seems foolish to assume that no similar patterns are possible. Let's do the CFI within scanGetItem's retry loop, instead. This demonstrably allows canceling out of the loop exhibited in bug #19031. Bug: #19031 Reported-by: Tim Wood Author: Tom Lane Discussion: https://postgr.es/m/19031-0638148643d25548@postgresql.org Backpatch-through: 13 --- src/backend/access/gin/ginget.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index 17601bb56b2..77d4a086dd1 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -1314,6 +1314,8 @@ scanGetItem(IndexScanDesc scan, ItemPointerData advancePast, */ do { + CHECK_FOR_INTERRUPTS(); + ItemPointerSetMin(item); match = true; for (i = 0; i < so->nkeys && match; i++) @@ -1953,8 +1955,6 @@ gingetbitmap(IndexScanDesc scan, TIDBitmap *tbm) for (;;) { - CHECK_FOR_INTERRUPTS(); - if (!scanGetItem(scan, iptr, &iptr, &recheck)) break;