apply_cost_limitation_get_actual_variable_endpoint.patch
application/octet-stream
Filename: apply_cost_limitation_get_actual_variable_endpoint.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/selfuncs.c | 17 | 2 |
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index d597b7e81f..c7a731c69f 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -6145,6 +6145,8 @@ get_actual_variable_endpoint(Relation heapRel,
Datum values[INDEX_MAX_KEYS];
bool isnull[INDEX_MAX_KEYS];
MemoryContext oldcontext;
+ double endpoint_cost = 0.0;
+ BlockNumber last_block = InvalidBlockNumber;
/*
* We use the index-only-scan machinery for this. With mostly-static
@@ -6197,13 +6199,26 @@ 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)
+ endpoint_cost += random_page_cost;
+ else
+ endpoint_cost += cpu_tuple_cost;
+ last_block = block;
+#define ENDPOINT_COST_LIMIT 20.0
+ if (endpoint_cost > ENDPOINT_COST_LIMIT)
+ break;
+ else
+ continue; /* no visible tuple, try next index entry */
+ }
/* We don't actually need the heap tuple for anything */
ExecClearTuple(tableslot);