Commit 8e2b71d2 authored by Tom Lane's avatar Tom Lane

Reset the binary heap in MergeAppend rescans.

Failing to do so can cause queries to return wrong data, error out or crash.
This requires adding a new binaryheap_reset() method to binaryheap.c,
but that probably should have been there anyway.

Per bug #8410 from Terje Elde.  Diagnosis and patch by Andres Freund.
parent 9381cb52
...@@ -297,5 +297,6 @@ ExecReScanMergeAppend(MergeAppendState *node) ...@@ -297,5 +297,6 @@ ExecReScanMergeAppend(MergeAppendState *node)
if (subnode->chgParam == NULL) if (subnode->chgParam == NULL)
ExecReScan(subnode); ExecReScan(subnode);
} }
binaryheap_reset(node->ms_heap);
node->ms_initialized = false; node->ms_initialized = false;
} }
...@@ -36,16 +36,30 @@ binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg) ...@@ -36,16 +36,30 @@ binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
binaryheap *heap; binaryheap *heap;
sz = offsetof(binaryheap, bh_nodes) +sizeof(Datum) * capacity; sz = offsetof(binaryheap, bh_nodes) +sizeof(Datum) * capacity;
heap = palloc(sz); heap = (binaryheap *) palloc(sz);
heap->bh_size = 0;
heap->bh_space = capacity; heap->bh_space = capacity;
heap->bh_has_heap_property = true;
heap->bh_compare = compare; heap->bh_compare = compare;
heap->bh_arg = arg; heap->bh_arg = arg;
heap->bh_size = 0;
heap->bh_has_heap_property = true;
return heap; return heap;
} }
/*
* binaryheap_reset
*
* Resets the heap to an empty state, losing its data content but not the
* parameters passed at allocation.
*/
void
binaryheap_reset(binaryheap *heap)
{
heap->bh_size = 0;
heap->bh_has_heap_property = true;
}
/* /*
* binaryheap_free * binaryheap_free
* *
......
...@@ -40,6 +40,7 @@ typedef struct binaryheap ...@@ -40,6 +40,7 @@ typedef struct binaryheap
extern binaryheap *binaryheap_allocate(int capacity, extern binaryheap *binaryheap_allocate(int capacity,
binaryheap_comparator compare, binaryheap_comparator compare,
void *arg); void *arg);
extern void binaryheap_reset(binaryheap *heap);
extern void binaryheap_free(binaryheap *heap); extern void binaryheap_free(binaryheap *heap);
extern void binaryheap_add_unordered(binaryheap *heap, Datum d); extern void binaryheap_add_unordered(binaryheap *heap, Datum d);
extern void binaryheap_build(binaryheap *heap); extern void binaryheap_build(binaryheap *heap);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment