summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2013-08-30 23:15:21 +0000
committerTom Lane2013-08-30 23:15:21 +0000
commit8e2b71d2d0381f7acc820a2400580a1e3a6add8c (patch)
tree2e419f5090c23820a43397c391627150bf7fae41
parent9381cb5229da1f3556909585b38ada347d798161 (diff)
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.
-rw-r--r--src/backend/executor/nodeMergeAppend.c1
-rw-r--r--src/backend/lib/binaryheap.c20
-rw-r--r--src/include/lib/binaryheap.h1
3 files changed, 19 insertions, 3 deletions
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,17 +36,31 @@ 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
*
* Releases memory used by the given binaryheap.
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);