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

Commit 7ab6f2d

Browse files
committed
Change inv_truncate() to not repeat its systable_getnext_ordered() scan.
In the case where the initial call of systable_getnext_ordered() returned NULL, this function would nonetheless call it again. That's undefined behavior that only by chance failed to not give visibly incorrect results. Put an if-test around the final loop to prevent that, and in passing improve some comments. No back-patch since there's no actual failure. Per report from YAMAMOTO Takashi.
1 parent 8b6f5f2 commit 7ab6f2d

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/backend/storage/large_object/inv_api.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,9 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
762762

763763
indstate = CatalogOpenIndexes(lo_heap_r);
764764

765+
/*
766+
* Set up to find all pages with desired loid and pageno >= target
767+
*/
765768
ScanKeyInit(&skey[0],
766769
Anum_pg_largeobject_loid,
767770
BTEqualStrategyNumber, F_OIDEQ,
@@ -841,10 +844,14 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
841844
{
842845
/*
843846
* If the first page we found was after the truncation point, we're in
844-
* a hole that we'll fill, but we need to delete the later page.
847+
* a hole that we'll fill, but we need to delete the later page because
848+
* the loop below won't visit it again.
845849
*/
846-
if (olddata != NULL && olddata->pageno > pageno)
850+
if (olddata != NULL)
851+
{
852+
Assert(olddata->pageno > pageno);
847853
simple_heap_delete(lo_heap_r, &oldtuple->t_self);
854+
}
848855

849856
/*
850857
* Write a brand new page.
@@ -873,11 +880,15 @@ inv_truncate(LargeObjectDesc *obj_desc, int len)
873880
}
874881

875882
/*
876-
* Delete any pages after the truncation point
883+
* Delete any pages after the truncation point. If the initial search
884+
* didn't find a page, then of course there's nothing more to do.
877885
*/
878-
while ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
886+
if (olddata != NULL)
879887
{
880-
simple_heap_delete(lo_heap_r, &oldtuple->t_self);
888+
while ((oldtuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
889+
{
890+
simple_heap_delete(lo_heap_r, &oldtuple->t_self);
891+
}
881892
}
882893

883894
systable_endscan_ordered(sd);

0 commit comments

Comments
 (0)