From: Tom Lane Date: Fri, 30 Aug 2013 23:15:21 +0000 (-0400) Subject: Reset the binary heap in MergeAppend rescans. X-Git-Tag: REL9_4_BETA1~1188 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8e2b71d2d0381f7acc820a2400580a1e3a6add8c;p=postgresql 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. --- diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index 5a48f7ab13..c3edd61859 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -297,5 +297,6 @@ ExecReScanMergeAppend(MergeAppendState *node) if (subnode->chgParam == NULL) ExecReScan(subnode); } + binaryheap_reset(node->ms_heap); node->ms_initialized = false; } diff --git a/src/backend/lib/binaryheap.c b/src/backend/lib/binaryheap.c index 4b4fc945c3..7125970a50 100644 --- a/src/backend/lib/binaryheap.c +++ b/src/backend/lib/binaryheap.c @@ -36,16 +36,30 @@ binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg) binaryheap *heap; sz = offsetof(binaryheap, bh_nodes) +sizeof(Datum) * capacity; - heap = palloc(sz); - heap->bh_size = 0; + heap = (binaryheap *) palloc(sz); heap->bh_space = capacity; - heap->bh_has_heap_property = true; heap->bh_compare = compare; heap->bh_arg = arg; + heap->bh_size = 0; + heap->bh_has_heap_property = true; + 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 * diff --git a/src/include/lib/binaryheap.h b/src/include/lib/binaryheap.h index 1e99e72e51..85cafe4d4d 100644 --- a/src/include/lib/binaryheap.h +++ b/src/include/lib/binaryheap.h @@ -40,6 +40,7 @@ typedef struct binaryheap extern binaryheap *binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg); +extern void binaryheap_reset(binaryheap *heap); extern void binaryheap_free(binaryheap *heap); extern void binaryheap_add_unordered(binaryheap *heap, Datum d); extern void binaryheap_build(binaryheap *heap);