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

Lines changed: 16 additions & 11 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy