99 *
1010 *
1111 * IDENTIFICATION
12- * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.69 2000/06/05 07:28:45 tgl Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.70 2000/06/15 06: 07:34 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -187,6 +187,7 @@ inv_create(int flags)
187187retval -> idesc = RelationGetDescr (indr );
188188retval -> offset = retval -> lowbyte = retval -> highbyte = 0 ;
189189ItemPointerSetInvalid (& (retval -> htid ));
190+ retval -> flags = 0 ;
190191
191192if (flags & INV_WRITE )
192193{
@@ -198,7 +199,7 @@ inv_create(int flags)
198199LockRelation (r ,ShareLock );
199200retval -> flags = IFS_RDLOCK ;
200201}
201- retval -> flags |=IFS_ATEOF ;
202+ retval -> flags |=IFS_ATEOF ;/* since we know the object is empty */
202203
203204return retval ;
204205}
@@ -235,6 +236,7 @@ inv_open(Oid lobjId, int flags)
235236retval -> idesc = RelationGetDescr (indrel );
236237retval -> offset = retval -> lowbyte = retval -> highbyte = 0 ;
237238ItemPointerSetInvalid (& (retval -> htid ));
239+ retval -> flags = 0 ;
238240
239241if (flags & INV_WRITE )
240242{
@@ -373,14 +375,8 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
373375if (whence == SEEK_CUR )
374376{
375377offset += obj_desc -> offset ;/* calculate absolute position */
376- return inv_seek (obj_desc ,offset ,SEEK_SET );
377378}
378-
379- /*
380- * if you seek past the end (offset > 0) I have no clue what happens
381- * :-( B.L. 9/1/93
382- */
383- if (whence == SEEK_END )
379+ else if (whence == SEEK_END )
384380{
385381/* need read lock for getsize */
386382if (!(obj_desc -> flags & IFS_RDLOCK ))
@@ -391,8 +387,8 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
391387offset += _inv_getsize (obj_desc -> heap_r ,
392388obj_desc -> hdesc ,
393389obj_desc -> index_r );
394- return inv_seek (obj_desc ,offset ,SEEK_SET );
395390}
391+ /* now we can assume that the operation is SEEK_SET */
396392
397393/*
398394 * Whenever we do a seek, we turn off the EOF flag bit to force
@@ -416,17 +412,13 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
416412 * stores the offset of the last byte that appears on it, and we have
417413 * an index on this.
418414 */
419-
420-
421- /* right now, just assume that the operation is SEEK_SET */
422415if (obj_desc -> iscan != (IndexScanDesc )NULL )
423416{
424417d = Int32GetDatum (offset );
425418btmovescan (obj_desc -> iscan ,d );
426419}
427420else
428421{
429-
430422ScanKeyEntryInitialize (& skey ,0x0 ,1 ,F_INT4GE ,
431423Int32GetDatum (offset ));
432424
@@ -489,9 +481,27 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
489481
490482/* copy the data from this block into the buffer */
491483d = heap_getattr (& tuple ,2 ,obj_desc -> hdesc ,& isNull );
484+ fsblock = (struct varlena * )DatumGetPointer (d );
492485ReleaseBuffer (buffer );
493486
494- fsblock = (struct varlena * )DatumGetPointer (d );
487+ /*
488+ * If block starts beyond current seek point, then we are looking
489+ * at a "hole" (unwritten area) in the object. Return zeroes for
490+ * the "hole".
491+ */
492+ if (obj_desc -> offset < obj_desc -> lowbyte )
493+ {
494+ int nzeroes = obj_desc -> lowbyte - obj_desc -> offset ;
495+
496+ if (nzeroes > (nbytes - nread ))
497+ nzeroes = (nbytes - nread );
498+ MemSet (buf ,0 ,nzeroes );
499+ buf += nzeroes ;
500+ nread += nzeroes ;
501+ obj_desc -> offset += nzeroes ;
502+ if (nread >=nbytes )
503+ break ;
504+ }
495505
496506off = obj_desc -> offset - obj_desc -> lowbyte ;
497507ncopy = obj_desc -> highbyte - obj_desc -> offset + 1 ;
@@ -537,14 +547,11 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
537547Buffer buffer ;
538548
539549/*
540- * Fetch the current inversion file system block. If the class
541- * storing the inversion file is empty, we don't want to do an
542- * index lookup, since index lookups choke on empty files (should
543- * be fixed someday).
550+ * Fetch the current inversion file system block. We can skip
551+ * the work if we already know we are at EOF.
544552 */
545553
546- if ((obj_desc -> flags & IFS_ATEOF )
547- || obj_desc -> heap_r -> rd_nblocks == 0 )
554+ if (obj_desc -> flags & IFS_ATEOF )
548555tuple .t_data = NULL ;
549556else
550557inv_fetchtup (obj_desc ,& tuple ,& buffer );
@@ -659,6 +666,7 @@ inv_fetchtup(LargeObjectDesc *obj_desc, HeapTuple tuple, Buffer *buffer)
659666}
660667else
661668index_rescan (obj_desc -> iscan , false,& skey );
669+
662670do
663671{
664672res = index_getnext (obj_desc -> iscan ,ForwardScanDirection );
@@ -1149,7 +1157,8 @@ inv_indextup(LargeObjectDesc *obj_desc, HeapTuple tuple)
11491157pfree (res );
11501158}
11511159
1152- /*
1160+ #ifdef NOT_USED
1161+
11531162static void
11541163DumpPage (Page page ,int blkno )
11551164{
@@ -1239,7 +1248,8 @@ ItemPointerFormExternal(ItemPointer pointer)
12391248
12401249return itemPointerString ;
12411250}
1242- */
1251+
1252+ #endif
12431253
12441254static int
12451255_inv_getsize (Relation hreln ,TupleDesc hdesc ,Relation ireln )