mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -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)
 | 
				
			|||||||
	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
 | 
				
			|||||||
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);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user