]> granicus.if.org Git - postgresql/commitdiff
Reset the binary heap in MergeAppend rescans.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 30 Aug 2013 23:15:21 +0000 (19:15 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 30 Aug 2013 23:15:32 +0000 (19:15 -0400)
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.

src/backend/executor/nodeMergeAppend.c
src/backend/lib/binaryheap.c
src/include/lib/binaryheap.h

index 5a48f7ab13bd7f7a329c01c23a03c3d00c281472..c3edd61859137b77088508f0ddbe03e4560004f5 100644 (file)
@@ -297,5 +297,6 @@ ExecReScanMergeAppend(MergeAppendState *node)
                if (subnode->chgParam == NULL)
                        ExecReScan(subnode);
        }
+       binaryheap_reset(node->ms_heap);
        node->ms_initialized = false;
 }
index 4b4fc945c32e7b74c8721cb5942ce44a47f7384b..7125970a50fcf14b73fccc8158e000bc6c3fcf28 100644 (file)
@@ -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
  *
index 1e99e72e515a5bd0da84c5ac682d2acaf3b757a0..85cafe4d4dd9031860a38969ecd160a52d30b299 100644 (file)
@@ -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);