From 29b83839f606ab6418a2295429ab833efb86449e Mon Sep 17 00:00:00 2001 From: Jakub Wartak Date: Mon, 21 Nov 2022 16:52:34 +0100 Subject: [PATCH] Damage control for planner's get_actual_variable_endpoint() runaway Limit planner's get_actual_variable_endpoint to 100 pages. Discussion: https://www.postgresql.org/message-id/flat/CAKZiRmznOwi0oaV%3D4PHOCM4ygcH4MgSvt8%3D5cu_vNCfc8FSUug%40mail.gmail.com --- src/backend/utils/adt/selfuncs.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index e0aeaa6909..ad2c6078eb 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -6161,6 +6161,9 @@ get_actual_variable_endpoint(Relation heapRel, Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; MemoryContext oldcontext; + int visited_pages = 0; + BlockNumber last_block = InvalidBlockNumber; + /* * We use the index-only-scan machinery for this. With mostly-static @@ -6213,13 +6216,24 @@ get_actual_variable_endpoint(Relation heapRel, /* Fetch first/next tuple in specified direction */ while ((tid = index_getnext_tid(index_scan, indexscandir)) != NULL) { + BlockNumber block = ItemPointerGetBlockNumber(tid); if (!VM_ALL_VISIBLE(heapRel, - ItemPointerGetBlockNumber(tid), + block, &vmbuffer)) { /* Rats, we have to visit the heap to check visibility */ if (!index_fetch_heap(index_scan, tableslot)) - continue; /* no visible tuple, try next index entry */ + { + CHECK_FOR_INTERRUPTS(); + if (block != last_block) + visited_pages++; + last_block = block; +#define VISITED_PAGES_LIMIT 100 + if (visited_pages > VISITED_PAGES_LIMIT) + break; + else + continue; /* no visible tuple, try next index entry */ + } /* We don't actually need the heap tuple for anything */ ExecClearTuple(tableslot); -- 2.30.2