Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 94d8bbe

Browse files
committed
Improve inv_getsize() per suggestion from Denis Perchine; also fix
thinkos in inv_seek().
1 parent db263da commit 94d8bbe

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

src/backend/storage/large_object/inv_api.c

+16-11
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.79 2000/10/24 01:38:29 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.80 2000/11/02 23:52:06 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -186,7 +186,6 @@ inv_getsize(LargeObjectDesc *obj_desc)
186186
{
187187
bool found = false;
188188
uint32 lastbyte = 0;
189-
uint32 thislastbyte;
190189
ScanKeyData skey[1];
191190
IndexScanDesc sd;
192191
RetrieveIndexResult indexRes;
@@ -209,7 +208,13 @@ inv_getsize(LargeObjectDesc *obj_desc)
209208
tuple.t_datamcxt = CurrentMemoryContext;
210209
tuple.t_data = NULL;
211210

212-
while ((indexRes = index_getnext(sd, ForwardScanDirection)))
211+
/*
212+
* Because the pg_largeobject index is on both loid and pageno,
213+
* but we constrain only loid, a backwards scan should visit all
214+
* pages of the large object in reverse pageno order. So, it's
215+
* sufficient to examine the first valid tuple (== last valid page).
216+
*/
217+
while ((indexRes = index_getnext(sd, BackwardScanDirection)))
213218
{
214219
tuple.t_self = indexRes->heap_iptr;
215220
heap_fetch(obj_desc->heap_r, SnapshotNow, &tuple, &buffer);
@@ -226,12 +231,11 @@ inv_getsize(LargeObjectDesc *obj_desc)
226231
heap_tuple_untoast_attr((varattrib *) datafield);
227232
pfreeit = true;
228233
}
229-
thislastbyte = data->pageno * LOBLKSIZE + getbytealen(datafield);
230-
if (thislastbyte > lastbyte)
231-
lastbyte = thislastbyte;
234+
lastbyte = data->pageno * LOBLKSIZE + getbytealen(datafield);
232235
if (pfreeit)
233236
pfree(datafield);
234237
ReleaseBuffer(buffer);
238+
break;
235239
}
236240

237241
index_endscan(sd);
@@ -254,16 +258,17 @@ inv_seek(LargeObjectDesc *obj_desc, int offset, int whence)
254258
obj_desc->offset = offset;
255259
break;
256260
case SEEK_CUR:
257-
if ((obj_desc->offset + offset) < 0)
261+
if (offset < 0 && obj_desc->offset < ((uint32) (- offset)))
258262
elog(ERROR, "inv_seek: invalid offset: %d", offset);
259263
obj_desc->offset += offset;
260264
break;
261265
case SEEK_END:
262266
{
263-
uint32 size = inv_getsize(obj_desc);
264-
if (offset < 0 || ((uint32) offset) > size)
265-
elog(ERROR, "inv_seek: invalid offset");
266-
obj_desc->offset = size - offset;
267+
uint32 size = inv_getsize(obj_desc);
268+
269+
if (offset < 0 && size < ((uint32) (- offset)))
270+
elog(ERROR, "inv_seek: invalid offset: %d", offset);
271+
obj_desc->offset = size + offset;
267272
}
268273
break;
269274
default:

0 commit comments

Comments
 (0)