Commit 94d8bbe5 authored by Tom Lane's avatar Tom Lane

Improve inv_getsize() per suggestion from Denis Perchine; also fix

thinkos in inv_seek().
parent db263da4
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.79 2000/10/24 01:38:29 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.80 2000/11/02 23:52:06 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -186,7 +186,6 @@ inv_getsize(LargeObjectDesc *obj_desc) ...@@ -186,7 +186,6 @@ inv_getsize(LargeObjectDesc *obj_desc)
{ {
bool found = false; bool found = false;
uint32 lastbyte = 0; uint32 lastbyte = 0;
uint32 thislastbyte;
ScanKeyData skey[1]; ScanKeyData skey[1];
IndexScanDesc sd; IndexScanDesc sd;
RetrieveIndexResult indexRes; RetrieveIndexResult indexRes;
...@@ -209,7 +208,13 @@ inv_getsize(LargeObjectDesc *obj_desc) ...@@ -209,7 +208,13 @@ inv_getsize(LargeObjectDesc *obj_desc)
tuple.t_datamcxt = CurrentMemoryContext; tuple.t_datamcxt = CurrentMemoryContext;
tuple.t_data = NULL; tuple.t_data = NULL;
while ((indexRes = index_getnext(sd, ForwardScanDirection))) /*
* Because the pg_largeobject index is on both loid and pageno,
* but we constrain only loid, a backwards scan should visit all
* pages of the large object in reverse pageno order. So, it's
* sufficient to examine the first valid tuple (== last valid page).
*/
while ((indexRes = index_getnext(sd, BackwardScanDirection)))
{ {
tuple.t_self = indexRes->heap_iptr; tuple.t_self = indexRes->heap_iptr;
heap_fetch(obj_desc->heap_r, SnapshotNow, &tuple, &buffer); heap_fetch(obj_desc->heap_r, SnapshotNow, &tuple, &buffer);
...@@ -226,12 +231,11 @@ inv_getsize(LargeObjectDesc *obj_desc) ...@@ -226,12 +231,11 @@ inv_getsize(LargeObjectDesc *obj_desc)
heap_tuple_untoast_attr((varattrib *) datafield); heap_tuple_untoast_attr((varattrib *) datafield);
pfreeit = true; pfreeit = true;
} }
thislastbyte = data->pageno * LOBLKSIZE + getbytealen(datafield); lastbyte = data->pageno * LOBLKSIZE + getbytealen(datafield);
if (thislastbyte > lastbyte)
lastbyte = thislastbyte;
if (pfreeit) if (pfreeit)
pfree(datafield); pfree(datafield);
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
break;
} }
index_endscan(sd); index_endscan(sd);
...@@ -254,16 +258,17 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence) ...@@ -254,16 +258,17 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
obj_desc->offset = offset; obj_desc->offset = offset;
break; break;
case SEEK_CUR: case SEEK_CUR:
if ((obj_desc->offset + offset) < 0) if (offset < 0 && obj_desc->offset < ((uint32) (- offset)))
elog(ERROR, "inv_seek: invalid offset: %d", offset); elog(ERROR, "inv_seek: invalid offset: %d", offset);
obj_desc->offset += offset; obj_desc->offset += offset;
break; break;
case SEEK_END: case SEEK_END:
{ {
uint32 size = inv_getsize(obj_desc); uint32 size = inv_getsize(obj_desc);
if (offset < 0 || ((uint32) offset) > size)
elog(ERROR, "inv_seek: invalid offset"); if (offset < 0 && size < ((uint32) (- offset)))
obj_desc->offset = size - offset; elog(ERROR, "inv_seek: invalid offset: %d", offset);
obj_desc->offset = size + offset;
} }
break; break;
default: default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment