summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2013-08-30 23:15:21 +0000
committerTom Lane2013-08-30 23:15:32 +0000
commit16e8e36cebba8909ec01ca259f32e8dd40090657 (patch)
treea47835e60a8ebc11c675e30cbe40b380f3a27951
parentdfed97b744a4706d7c7b410667c0c5bc92d0eb8d (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 5a48f7ab13b..c3edd618591 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 4b4fc945c32..7125970a50f 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 1e99e72e515..85cafe4d4dd 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);