Subject: PrivateRefCount error

From: [email-masked] (Postgres System User)
Date: Mon, 5 Apr 93 02:25:13 -0700

Greetings from the swamp;
Below is a description of the lastest excursion through the looking
glass.  The error is real enough.  The condition described is correct.
The solution however could do with some knowledgeable scrutiny.  An
obivious poser would be the life expectancy of buffers in the scandesc
structures.  Do things upstream expect these buffers to maintain any
kind of persistence?
Thanks nmm.

	* heapam.c:(heap_restrpos)
	heap_restrpos() releases pbuf, cbuf, and nbuf in a set:
	    if (BufferIsValid(sdesc->rs_pbuf)) {
	    	ReleaseBuffer(sdesc->rs_pbuf);
	    }
	    if (BufferIsValid(sdesc->rs_cbuf)) {
	    	ReleaseBuffer(sdesc->rs_cbuf);
	    }
	    if (BufferIsValid(sdesc->rs_nbuf)) {
	    	ReleaseBuffer(sdesc->rs_nbuf);
	    }
	However, if the buffers had more than 1 reference (ie.
	PrivateRefCount[bufnum - 1] > 1) the buffer was not actually
	freed.  Therefore, the call to heapgettup() and subsequently
	RelationGetBufferWithBuffer() did not call BufferAlloc() and
	PrivateRefCount(bufnum - 1] was not incremented!  This could
	cause the following error to occur (in ExecNestedLoops
	especially.):
	WARN:Apr  4 05:27:37:HeapTupleGetRuleLock: Invalid buffer	
	
	The following appears to have solved the problem.  It incorporates
	the call to ReleaseBuffer() only if the rs_m?tid
	ItemPointerIs**NOT**Valid.  I would certainly appreciate someone
	more knowledgeable validating that I haven't plunged ineptly.

	if (!ItemPointerIsValid(&sdesc->rs_mptid)) {         
    	    sdesc->rs_ptup = NULL;                       
    	    sdesc->rs_pbuf = InvalidBuffer;              
    	    if (BufferIsValid(sdesc->rs_pbuf)) {         
    	      ReleaseBuffer(sdesc->rs_pbuf);             
    	    }                                            
    	} else {                                         
    	    sdesc->rs_ptup = (HeapTuple)                 
    	        heapgettup(sdesc->rs_rd,                 
    	                   &sdesc->rs_mptid,             
    	                   0,                            
    	                   &sdesc->rs_pbuf,              
    	                   NowTimeQual,                  
    	                   0,                            
    	                   (ScanKey) NULL,               
    	                   sdesc->rs_parallel_ok);       
    	}                                                
	                                                 
    	if (!ItemPointerIsValid(&sdesc->rs_mctid)) {     
    	    sdesc->rs_ctup = NULL;                       
    	    sdesc->rs_cbuf = InvalidBuffer;              
    	    if (BufferIsValid(sdesc->rs_cbuf)) {         
    	      ReleaseBuffer(sdesc->rs_cbuf);             
    	    }                                            
    	} else {                                         
    	    sdesc->rs_ctup = (HeapTuple)                 
    	        heapgettup(sdesc->rs_rd,                 
    	                   &sdesc->rs_mctid,             
    	                   0,                            
    	                   &sdesc->rs_cbuf,              
    	                   NowTimeQual,                  
    	                   0,                            
    	                   (ScanKey) NULL,               
    	                   sdesc->rs_parallel_ok);       
    	}                                                
	                                                 
    	if (!ItemPointerIsValid(&sdesc->rs_mntid)) {     
    	    sdesc->rs_ntup = NULL;                       
    	    sdesc->rs_nbuf = InvalidBuffer;              
    	    if (BufferIsValid(sdesc->rs_nbuf)) {         
    	      ReleaseBuffer(sdesc->rs_nbuf);             
    	    }                                            
    	} else {                                         
    	    sdesc->rs_ntup = (HeapTuple)                 
    	        heapgettup(sdesc->rs_rd,                 
    	                   &sdesc->rs_mntid,             
    	                   0,                            
    	                   &sdesc->rs_nbuf,              
    	                   NowTimeQual,                  
    	                   0,                            
    	                   (ScanKey) NULL,               
    	                   sdesc->rs_parallel_ok);       
    	    }                                            

Neil M. McQuaig      344 Millicent Way,  Shreveport, LA  71106
VOICE: (318)868-5611 UUCP: mcquaig!nmm (318)861-1051 or uunet!mcquaig!nmm