|
8 | 8 | * |
9 | 9 | * |
10 | 10 | * IDENTIFICATION |
11 | | - * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.50 1999/02/22 16:46:43 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.51 1999/03/14 16:08:17 momjian Exp $ |
12 | 12 | * |
13 | 13 | *------------------------------------------------------------------------- |
14 | 14 | */ |
|
72 | 72 | *For subsequent notes, [PA] is Pascal André <andre@via.ecp.fr> |
73 | 73 | */ |
74 | 74 |
|
75 | | -#defineIFREESPC(p)(PageGetFreeSpace(p) - sizeof(HeapTupleData) - sizeof(struct varlena) - sizeof(int32)) |
| 75 | +#defineIFREESPC(p)(PageGetFreeSpace(p) - \ |
| 76 | + DOUBLEALIGN(offsetof(HeapTupleHeaderData,t_bits)) - \ |
| 77 | + DOUBLEALIGN(sizeof(struct varlena) + sizeof(int32)) - \ |
| 78 | + sizeof(double)) |
76 | 79 | #defineIMAXBLK8092 |
77 | 80 | #defineIMINBLK512 |
78 | 81 |
|
@@ -623,24 +626,25 @@ inv_fetchtup(LargeObjectDesc *obj_desc, HeapTuple tuple, Buffer *buffer) |
623 | 626 | ||obj_desc->offset<obj_desc->lowbyte |
624 | 627 | || !ItemPointerIsValid(&(obj_desc->htid))) |
625 | 628 | { |
| 629 | +ScanKeyDataskey; |
| 630 | + |
| 631 | +ScanKeyEntryInitialize(&skey,0x0,1,F_INT4GE, |
| 632 | +Int32GetDatum(obj_desc->offset)); |
626 | 633 |
|
627 | 634 | /* initialize scan key if not done */ |
628 | 635 | if (obj_desc->iscan== (IndexScanDesc)NULL) |
629 | 636 | { |
630 | | -ScanKeyDataskey; |
631 | | - |
632 | 637 | /* |
633 | 638 | * As scan index may be prematurely closed (on commit), we |
634 | 639 | * must use object current offset (was 0) to reinitialize the |
635 | 640 | * entry [ PA ]. |
636 | 641 | */ |
637 | | -ScanKeyEntryInitialize(&skey,0x0,1,F_INT4GE, |
638 | | -Int32GetDatum(obj_desc->offset)); |
639 | 642 | obj_desc->iscan=index_beginscan(obj_desc->index_r, |
640 | 643 | (bool)0, (uint16)1, |
641 | 644 | &skey); |
642 | | -} |
643 | | - |
| 645 | +}else { |
| 646 | +index_rescan(obj_desc->iscan, false,&skey); |
| 647 | + } |
644 | 648 | do |
645 | 649 | { |
646 | 650 | res=index_getnext(obj_desc->iscan,ForwardScanDirection); |
@@ -673,6 +677,9 @@ inv_fetchtup(LargeObjectDesc *obj_desc, HeapTuple tuple, Buffer *buffer) |
673 | 677 | { |
674 | 678 | tuple->t_self=obj_desc->htid; |
675 | 679 | heap_fetch(obj_desc->heap_r,SnapshotNow,tuple,buffer); |
| 680 | +if (tuple->t_data==NULL) { |
| 681 | +elog(ERROR,"inv_fetchtup: heap_fetch failed"); |
| 682 | + } |
676 | 683 | } |
677 | 684 |
|
678 | 685 | /* |
@@ -744,12 +751,15 @@ inv_wrnew(LargeObjectDesc *obj_desc, char *buf, int nbytes) |
744 | 751 |
|
745 | 752 | nblocks=RelationGetNumberOfBlocks(hr); |
746 | 753 |
|
747 | | -if (nblocks>0) |
| 754 | +if (nblocks>0) { |
748 | 755 | buffer=ReadBuffer(hr,nblocks-1); |
749 | | -else |
| 756 | +page=BufferGetPage(buffer); |
| 757 | +} |
| 758 | +else { |
750 | 759 | buffer=ReadBuffer(hr,P_NEW); |
751 | | - |
752 | | -page=BufferGetPage(buffer); |
| 760 | +page=BufferGetPage(buffer); |
| 761 | +PageInit(page,BufferGetPageSize(buffer),0); |
| 762 | +} |
753 | 763 |
|
754 | 764 | /* |
755 | 765 | * If the last page is too small to hold all the data, and it's too |
@@ -864,12 +874,16 @@ inv_wrold(LargeObjectDesc *obj_desc, |
864 | 874 |
|
865 | 875 | nblocks=RelationGetNumberOfBlocks(hr); |
866 | 876 |
|
867 | | -if (nblocks>0) |
| 877 | +if (nblocks>0) { |
868 | 878 | newbuf=ReadBuffer(hr,nblocks-1); |
869 | | -else |
| 879 | +newpage=BufferGetPage(newbuf); |
| 880 | +} |
| 881 | +else { |
870 | 882 | newbuf=ReadBuffer(hr,P_NEW); |
| 883 | +newpage=BufferGetPage(newbuf); |
| 884 | +PageInit(newpage,BufferGetPageSize(newbuf),0); |
| 885 | +} |
871 | 886 |
|
872 | | -newpage=BufferGetPage(newbuf); |
873 | 887 | freespc=IFREESPC(newpage); |
874 | 888 |
|
875 | 889 | /* |
@@ -974,6 +988,9 @@ inv_wrold(LargeObjectDesc *obj_desc, |
974 | 988 | if (newbuf!=buffer) |
975 | 989 | WriteBuffer(newbuf); |
976 | 990 |
|
| 991 | +/* Tuple id is no longer valid */ |
| 992 | +ItemPointerSetInvalid(&(obj_desc->htid)); |
| 993 | + |
977 | 994 | /* done */ |
978 | 995 | returnnwritten; |
979 | 996 | } |
|