[CURRENT] large object fix

Started by Tatsuo Ishiialmost 27 years ago2 messages
#1Tatsuo Ishii
t-ishii@sra.co.jp

To Bruce:
Thanks for taking care of my previous patches for current. If
included patch is ok, I will make one for current.

Now I'm working on lobj in current tree(Currently lobj in 6.5 seems
broken).

Done.

o overwriting an existing lobj now works
o 8KB garbage block always inserted problem is fixed

--
Tatsuo Ishii
--------------------------- cut here ---------------------------------
*** pgsql/src/backend/storage/large_object/inv_api.c.orig	Wed Feb 24 12:45:24 1999
--- pgsql/src/backend/storage/large_object/inv_api.c	Thu Feb 25 15:58:10 1999
***************
*** 72,78 ****
   *		For subsequent notes, [PA] is Pascal Andr,Ai(B <andre@via.ecp.fr>
   */

! #define IFREESPC(p) (PageGetFreeSpace(p) - sizeof(HeapTupleData) - sizeof(struct varlena) - sizeof(int32))
#define IMAXBLK 8092
#define IMINBLK 512

--- 72,81 ----
   *		For subsequent notes, [PA] is Pascal Andr,Ai(B <andre@via.ecp.fr>
   */

! #define IFREESPC(p) (PageGetFreeSpace(p) - \
! DOUBLEALIGN(offsetof(HeapTupleHeaderData,t_bits)) - \
! DOUBLEALIGN(sizeof(struct varlena) + sizeof(int32)) - \
! sizeof(double))
#define IMAXBLK 8092
#define IMINBLK 512

***************
*** 623,646 ****
|| obj_desc->offset < obj_desc->lowbyte
|| !ItemPointerIsValid(&(obj_desc->htid)))
{

  		/* initialize scan key if not done */
  		if (obj_desc->iscan == (IndexScanDesc) NULL)
  		{
- 			ScanKeyData skey;
- 
  			/*
  			 * As scan index may be prematurely closed (on commit), we
  			 * must use object current offset (was 0) to reinitialize the
  			 * entry [ PA ].
  			 */
- 			ScanKeyEntryInitialize(&skey, 0x0, 1, F_INT4GE,
- 								   Int32GetDatum(obj_desc->offset));
  			obj_desc->iscan = index_beginscan(obj_desc->index_r,
  								(bool) 0, (uint16) 1,
  								&skey);
! 		}
! 
  		do
  		{
  			res = index_getnext(obj_desc->iscan, ForwardScanDirection);
--- 626,650 ----
  		|| obj_desc->offset < obj_desc->lowbyte
  		|| !ItemPointerIsValid(&(obj_desc->htid)))
  	{
+  		ScanKeyData skey;
+ 
+ 		ScanKeyEntryInitialize(&skey, 0x0, 1, F_INT4GE,
+ 				       Int32GetDatum(obj_desc->offset));
  		/* initialize scan key if not done */
  		if (obj_desc->iscan == (IndexScanDesc) NULL)
  		{
  			/*
  			 * As scan index may be prematurely closed (on commit), we
  			 * must use object current offset (was 0) to reinitialize the
  			 * entry [ PA ].
  			 */
  			obj_desc->iscan = index_beginscan(obj_desc->index_r,
  								(bool) 0, (uint16) 1,
  								&skey);
! 		} else {
!  			index_rescan(obj_desc->iscan, false, &skey);
!         	}
  		do
  		{
  			res = index_getnext(obj_desc->iscan, ForwardScanDirection);
***************
*** 673,678 ****
--- 677,685 ----
  	{
  		tuple->t_self = obj_desc->htid;
  		heap_fetch(obj_desc->heap_r, SnapshotNow, tuple, buffer);
+  		if (tuple->t_data == NULL) {
+ 			elog(ERROR, "inv_fetchtup: heap_fetch failed");
+  		}
  	}

/*
***************
*** 744,755 ****

nblocks = RelationGetNumberOfBlocks(hr);

! if (nblocks > 0)
buffer = ReadBuffer(hr, nblocks - 1);
! else
buffer = ReadBuffer(hr, P_NEW);
!
! page = BufferGetPage(buffer);

  	/*
  	 * If the last page is too small to hold all the data, and it's too
--- 751,765 ----

nblocks = RelationGetNumberOfBlocks(hr);

! if (nblocks > 0) {
buffer = ReadBuffer(hr, nblocks - 1);
! page = BufferGetPage(buffer);
! }
! else {
buffer = ReadBuffer(hr, P_NEW);
! page = BufferGetPage(buffer);
! PageInit(page, BufferGetPageSize(buffer), 0);
! }

/*
* If the last page is too small to hold all the data, and it's too
***************
*** 864,875 ****

nblocks = RelationGetNumberOfBlocks(hr);

! if (nblocks > 0)
newbuf = ReadBuffer(hr, nblocks - 1);
! else
newbuf = ReadBuffer(hr, P_NEW);

- newpage = BufferGetPage(newbuf);
freespc = IFREESPC(newpage);

  		/*
--- 874,889 ----

nblocks = RelationGetNumberOfBlocks(hr);

! 		if (nblocks > 0) {
  			newbuf = ReadBuffer(hr, nblocks - 1);
! 			newpage = BufferGetPage(newbuf);
! 		}
! 		else {
  			newbuf = ReadBuffer(hr, P_NEW);
+ 			newpage = BufferGetPage(newbuf);
+ 			PageInit(newpage, BufferGetPageSize(newbuf), 0);
+ 		}

freespc = IFREESPC(newpage);

  		/*
***************
*** 973,978 ****
--- 987,995 ----
  	WriteBuffer(buffer);
  	if (newbuf != buffer)
  		WriteBuffer(newbuf);
+ 
+ 	/* Tuple id is no longer valid */
+ 	ItemPointerSetInvalid(&(obj_desc->htid));

/* done */
return nwritten;

#2Bruce Momjian
maillist@candle.pha.pa.us
In reply to: Tatsuo Ishii (#1)
Re: [HACKERS] [CURRENT] large object fix

Applied.

To Bruce:
Thanks for taking care of my previous patches for current. If
included patch is ok, I will make one for current.

Now I'm working on lobj in current tree(Currently lobj in 6.5 seems
broken).

Done.

o overwriting an existing lobj now works
o 8KB garbage block always inserted problem is fixed

--
Tatsuo Ishii
--------------------------- cut here ---------------------------------
*** pgsql/src/backend/storage/large_object/inv_api.c.orig	Wed Feb 24 12:45:24 1999
--- pgsql/src/backend/storage/large_object/inv_api.c	Thu Feb 25 15:58:10 1999
***************
*** 72,78 ****
*		For subsequent notes, [PA] is Pascal Andr,Ai(B <andre@via.ecp.fr>
*/

! #define IFREESPC(p) (PageGetFreeSpace(p) - sizeof(HeapTupleData) - sizeof(struct varlena) - sizeof(int32))
#define IMAXBLK 8092
#define IMINBLK 512

--- 72,81 ----
*		For subsequent notes, [PA] is Pascal Andr,Ai(B <andre@via.ecp.fr>
*/

! #define IFREESPC(p) (PageGetFreeSpace(p) - \
! DOUBLEALIGN(offsetof(HeapTupleHeaderData,t_bits)) - \
! DOUBLEALIGN(sizeof(struct varlena) + sizeof(int32)) - \
! sizeof(double))
#define IMAXBLK 8092
#define IMINBLK 512

***************
*** 623,646 ****
|| obj_desc->offset < obj_desc->lowbyte
|| !ItemPointerIsValid(&(obj_desc->htid)))
{

/* initialize scan key if not done */
if (obj_desc->iscan == (IndexScanDesc) NULL)
{
- 			ScanKeyData skey;
- 
/*
* As scan index may be prematurely closed (on commit), we
* must use object current offset (was 0) to reinitialize the
* entry [ PA ].
*/
- 			ScanKeyEntryInitialize(&skey, 0x0, 1, F_INT4GE,
- 								   Int32GetDatum(obj_desc->offset));
obj_desc->iscan = index_beginscan(obj_desc->index_r,
(bool) 0, (uint16) 1,
&skey);
! 		}
! 
do
{
res = index_getnext(obj_desc->iscan, ForwardScanDirection);
--- 626,650 ----
|| obj_desc->offset < obj_desc->lowbyte
|| !ItemPointerIsValid(&(obj_desc->htid)))
{
+  		ScanKeyData skey;
+ 
+ 		ScanKeyEntryInitialize(&skey, 0x0, 1, F_INT4GE,
+ 				       Int32GetDatum(obj_desc->offset));
/* initialize scan key if not done */
if (obj_desc->iscan == (IndexScanDesc) NULL)
{
/*
* As scan index may be prematurely closed (on commit), we
* must use object current offset (was 0) to reinitialize the
* entry [ PA ].
*/
obj_desc->iscan = index_beginscan(obj_desc->index_r,
(bool) 0, (uint16) 1,
&skey);
! 		} else {
!  			index_rescan(obj_desc->iscan, false, &skey);
!         	}
do
{
res = index_getnext(obj_desc->iscan, ForwardScanDirection);
***************
*** 673,678 ****
--- 677,685 ----
{
tuple->t_self = obj_desc->htid;
heap_fetch(obj_desc->heap_r, SnapshotNow, tuple, buffer);
+  		if (tuple->t_data == NULL) {
+ 			elog(ERROR, "inv_fetchtup: heap_fetch failed");
+  		}
}

/*
***************
*** 744,755 ****

nblocks = RelationGetNumberOfBlocks(hr);

! if (nblocks > 0)
buffer = ReadBuffer(hr, nblocks - 1);
! else
buffer = ReadBuffer(hr, P_NEW);
!
! page = BufferGetPage(buffer);

/*
* If the last page is too small to hold all the data, and it's too
--- 751,765 ----

nblocks = RelationGetNumberOfBlocks(hr);

! if (nblocks > 0) {
buffer = ReadBuffer(hr, nblocks - 1);
! page = BufferGetPage(buffer);
! }
! else {
buffer = ReadBuffer(hr, P_NEW);
! page = BufferGetPage(buffer);
! PageInit(page, BufferGetPageSize(buffer), 0);
! }

/*
* If the last page is too small to hold all the data, and it's too
***************
*** 864,875 ****

nblocks = RelationGetNumberOfBlocks(hr);

! if (nblocks > 0)
newbuf = ReadBuffer(hr, nblocks - 1);
! else
newbuf = ReadBuffer(hr, P_NEW);

- newpage = BufferGetPage(newbuf);
freespc = IFREESPC(newpage);

/*
--- 874,889 ----

nblocks = RelationGetNumberOfBlocks(hr);

! 		if (nblocks > 0) {
newbuf = ReadBuffer(hr, nblocks - 1);
! 			newpage = BufferGetPage(newbuf);
! 		}
! 		else {
newbuf = ReadBuffer(hr, P_NEW);
+ 			newpage = BufferGetPage(newbuf);
+ 			PageInit(newpage, BufferGetPageSize(newbuf), 0);
+ 		}

freespc = IFREESPC(newpage);

/*
***************
*** 973,978 ****
--- 987,995 ----
WriteBuffer(buffer);
if (newbuf != buffer)
WriteBuffer(newbuf);
+ 
+ 	/* Tuple id is no longer valid */
+ 	ItemPointerSetInvalid(&(obj_desc->htid));

/* done */
return nwritten;

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026