summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2000-06-15 06:10:27 +0000
committerTom Lane2000-06-15 06:10:27 +0000
commit55742d4b1c5dee4cd94132e996d6b8654f3fc0eb (patch)
tree8ba0f9ee4fb2dd5b715ebe9d2f56e9324365b765
parentc545ec54f8139e7f02e39a138fc5f21ebdc33b7b (diff)
Back-patch large-object fix.
-rw-r--r--src/backend/storage/large_object/inv_api.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index 38961ff34c1..34210a2ac3a 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.67 2000/04/12 17:15:37 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.67.2.1 2000/06/15 06:10:27 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -185,6 +185,7 @@ inv_create(int flags)
retval->idesc = RelationGetDescr(indr);
retval->offset = retval->lowbyte = retval->highbyte = 0;
ItemPointerSetInvalid(&(retval->htid));
+ retval->flags = 0;
if (flags & INV_WRITE)
{
@@ -196,7 +197,7 @@ inv_create(int flags)
LockRelation(r, ShareLock);
retval->flags = IFS_RDLOCK;
}
- retval->flags |= IFS_ATEOF;
+ retval->flags |= IFS_ATEOF; /* since we know the object is empty */
return retval;
}
@@ -233,6 +234,7 @@ inv_open(Oid lobjId, int flags)
retval->idesc = RelationGetDescr(indrel);
retval->offset = retval->lowbyte = retval->highbyte = 0;
ItemPointerSetInvalid(&(retval->htid));
+ retval->flags = 0;
if (flags & INV_WRITE)
{
@@ -371,14 +373,8 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
if (whence == SEEK_CUR)
{
offset += obj_desc->offset; /* calculate absolute position */
- return inv_seek(obj_desc, offset, SEEK_SET);
}
-
- /*
- * if you seek past the end (offset > 0) I have no clue what happens
- * :-( B.L. 9/1/93
- */
- if (whence == SEEK_END)
+ else if (whence == SEEK_END)
{
/* need read lock for getsize */
if (!(obj_desc->flags & IFS_RDLOCK))
@@ -389,8 +385,8 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
offset += _inv_getsize(obj_desc->heap_r,
obj_desc->hdesc,
obj_desc->index_r);
- return inv_seek(obj_desc, offset, SEEK_SET);
}
+ /* now we can assume that the operation is SEEK_SET */
/*
* Whenever we do a seek, we turn off the EOF flag bit to force
@@ -414,9 +410,6 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
* stores the offset of the last byte that appears on it, and we have
* an index on this.
*/
-
-
- /* right now, just assume that the operation is SEEK_SET */
if (obj_desc->iscan != (IndexScanDesc) NULL)
{
d = Int32GetDatum(offset);
@@ -424,7 +417,6 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
}
else
{
-
ScanKeyEntryInitialize(&skey, 0x0, 1, F_INT4GE,
Int32GetDatum(offset));
@@ -487,9 +479,27 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
/* copy the data from this block into the buffer */
d = heap_getattr(&tuple, 2, obj_desc->hdesc, &isNull);
+ fsblock = (struct varlena *) DatumGetPointer(d);
ReleaseBuffer(buffer);
- fsblock = (struct varlena *) DatumGetPointer(d);
+ /*
+ * If block starts beyond current seek point, then we are looking
+ * at a "hole" (unwritten area) in the object. Return zeroes for
+ * the "hole".
+ */
+ if (obj_desc->offset < obj_desc->lowbyte)
+ {
+ int nzeroes = obj_desc->lowbyte - obj_desc->offset;
+
+ if (nzeroes > (nbytes - nread))
+ nzeroes = (nbytes - nread);
+ MemSet(buf, 0, nzeroes);
+ buf += nzeroes;
+ nread += nzeroes;
+ obj_desc->offset += nzeroes;
+ if (nread >= nbytes)
+ break;
+ }
off = obj_desc->offset - obj_desc->lowbyte;
ncopy = obj_desc->highbyte - obj_desc->offset + 1;
@@ -535,14 +545,11 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Buffer buffer;
/*
- * Fetch the current inversion file system block. If the class
- * storing the inversion file is empty, we don't want to do an
- * index lookup, since index lookups choke on empty files (should
- * be fixed someday).
+ * Fetch the current inversion file system block. We can skip
+ * the work if we already know we are at EOF.
*/
- if ((obj_desc->flags & IFS_ATEOF)
- || obj_desc->heap_r->rd_nblocks == 0)
+ if (obj_desc->flags & IFS_ATEOF)
tuple.t_data = NULL;
else
inv_fetchtup(obj_desc, &tuple, &buffer);
@@ -657,6 +664,7 @@ inv_fetchtup(LargeObjectDesc *obj_desc, HeapTuple tuple, Buffer *buffer)
}
else
index_rescan(obj_desc->iscan, false, &skey);
+
do
{
res = index_getnext(obj_desc->iscan, ForwardScanDirection);
@@ -1147,7 +1155,8 @@ inv_indextup(LargeObjectDesc *obj_desc, HeapTuple tuple)
pfree(res);
}
-/*
+#ifdef NOT_USED
+
static void
DumpPage(Page page, int blkno)
{
@@ -1237,7 +1246,8 @@ ItemPointerFormExternal(ItemPointer pointer)
return itemPointerString;
}
-*/
+
+#endif
static int
_inv_getsize(Relation hreln, TupleDesc hdesc, Relation ireln)