Skip to content

Commit 793829d

Browse files
committed
PGPRO-2554: Copy an additional information into the current memory
In case of concurrent updates reading raw additional information from index pages may lead to undefined behaviour.
1 parent 6230579 commit 793829d

File tree

6 files changed

+37
-21
lines changed

6 files changed

+37
-21
lines changed

src/rum.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "access/sdir.h"
2020
#include "lib/rbtree.h"
2121
#include "storage/bufmgr.h"
22+
#include "utils/datum.h"
2223

2324
#include "rumsort.h"
2425

@@ -529,7 +530,7 @@ extern void rumEntryFillRoot(RumBtree btree, Buffer root, Buffer lbuf, Buffer rb
529530
Page page, Page lpage, Page rpage);
530531
extern IndexTuple rumPageGetLinkItup(RumBtree btree, Buffer buf, Page page);
531532
extern void rumReadTuple(RumState * rumstate, OffsetNumber attnum,
532-
IndexTuple itup, RumItem * items);
533+
IndexTuple itup, RumItem * items, bool copyAddInfo);
533534
extern void rumReadTuplePointers(RumState * rumstate, OffsetNumber attnum,
534535
IndexTuple itup, ItemPointerData *ipd);
535536
extern void updateItemIndexes(Page page, OffsetNumber attnum, RumState * rumstate);
@@ -941,10 +942,14 @@ rumDataPageLeafReadItemPointer(char *ptr, ItemPointer iptr, bool *addInfoIsNull)
941942
* Reads next item pointer and additional information from leaf data page.
942943
* Replaces current item pointer with the next one. Zero item pointer should be
943944
* passed in order to read the first item pointer.
945+
*
946+
* It is necessary to pass copyAddInfo=true if additional information is used
947+
* when the data page is unlocked. If the additional information is used without
948+
* locking one can get unexpected behaviour.
944949
*/
945950
static inline Pointer
946951
rumDataPageLeafRead(Pointer ptr, OffsetNumber attnum, RumItem * item,
947-
RumState * rumstate)
952+
bool copyAddInfo, RumState * rumstate)
948953
{
949954
Form_pg_attribute attr;
950955

@@ -1009,8 +1014,13 @@ rumDataPageLeafRead(Pointer ptr, OffsetNumber attnum, RumItem * item,
10091014
}
10101015
else
10111016
{
1012-
ptr = (Pointer) att_align_pointer(ptr, attr->attalign, attr->attlen, ptr);
1013-
item->addInfo = fetch_att(ptr, attr->attbyval, attr->attlen);
1017+
Datum addInfo;
1018+
1019+
ptr = (Pointer) att_align_pointer(ptr, attr->attalign, attr->attlen,
1020+
ptr);
1021+
addInfo = fetch_att(ptr, attr->attbyval, attr->attlen);
1022+
item->addInfo = copyAddInfo ?
1023+
datumCopy(addInfo, attr->attbyval, attr->attlen) : addInfo;
10141024
}
10151025

10161026
ptr = (Pointer) att_addlength_pointer(ptr, attr->attlen, ptr);

src/rumdatapage.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ findInLeafPage(RumBtree btree, Page page, OffsetNumber *offset,
589589
*iptrOut = item.iptr;
590590

591591
ptr = rumDataPageLeafRead(ptr, btree->entryAttnum, &item,
592-
btree->rumstate);
592+
false, btree->rumstate);
593593

594594
cmp = compareRumItem(btree->rumstate, btree->entryAttnum,
595595
&btree->items[btree->curitem], &item);
@@ -899,7 +899,8 @@ dataPlaceToPage(RumBtree btree, Page page, OffsetNumber off)
899899
if (copyItemEmpty == true && off <= maxoff)
900900
{
901901
copyPtr = rumDataPageLeafRead(copyPtr, btree->entryAttnum,
902-
&copyItem, btree->rumstate);
902+
&copyItem, false,
903+
btree->rumstate);
903904
copyItemEmpty = false;
904905
}
905906

@@ -1091,7 +1092,7 @@ dataSplitPageLeaf(RumBtree btree, Buffer lbuf, Buffer rbuf,
10911092

10921093
prevIptr = item.iptr;
10931094
copyPtr = rumDataPageLeafRead(copyPtr, btree->entryAttnum, &item,
1094-
btree->rumstate);
1095+
false, btree->rumstate);
10951096

10961097
prevTotalsize = totalsize;
10971098
totalsize = rumCheckPlaceToDataPageLeaf(btree->entryAttnum,
@@ -1169,7 +1170,7 @@ dataSplitPageLeaf(RumBtree btree, Buffer lbuf, Buffer rbuf,
11691170
}
11701171

11711172
copyPtr = rumDataPageLeafRead(copyPtr, btree->entryAttnum, &item,
1172-
btree->rumstate);
1173+
false, btree->rumstate);
11731174

11741175
curItem = item;
11751176
ptr = rumPlaceToDataPageLeaf(ptr, btree->entryAttnum, &item,
@@ -1351,7 +1352,7 @@ updateItemIndexes(Page page, OffsetNumber attnum, RumState * rumstate)
13511352
}
13521353
j++;
13531354
}
1354-
ptr = rumDataPageLeafRead(ptr, attnum, &item, rumstate);
1355+
ptr = rumDataPageLeafRead(ptr, attnum, &item, false, rumstate);
13551356
}
13561357
/* Fill rest of page indexes with InvalidOffsetNumber if any */
13571358
for (; j < RumDataLeafIndexCount; j++)

src/rumentrypage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*/
2222
void
2323
rumReadTuple(RumState * rumstate, OffsetNumber attnum,
24-
IndexTuple itup, RumItem * items)
24+
IndexTuple itup, RumItem * items, bool copyAddInfo)
2525
{
2626
Pointer ptr = RumGetPosting(itup);
2727
RumItem item;
@@ -31,7 +31,7 @@ rumReadTuple(RumState * rumstate, OffsetNumber attnum,
3131
ItemPointerSetMin(&item.iptr);
3232
for (i = 0; i < nipd; i++)
3333
{
34-
ptr = rumDataPageLeafRead(ptr, attnum, &item, rumstate);
34+
ptr = rumDataPageLeafRead(ptr, attnum, &item, copyAddInfo, rumstate);
3535
items[i] = item;
3636
}
3737
}

src/rumget.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ scanPostingTree(Relation index, RumScanEntry scanEntry,
258258
ptr = RumDataPageGetData(page);
259259
for (i = FirstOffsetNumber; i <= maxoff; i++)
260260
{
261-
ptr = rumDataPageLeafRead(ptr, attnum, &item.item, rumstate);
261+
ptr = rumDataPageLeafRead(ptr, attnum, &item.item, false,
262+
rumstate);
262263
SCAN_ITEM_PUT_KEY(scanEntry, item, idatum, icategory);
263264
rum_tuplesort_putrumitem(scanEntry->matchSortstate, &item);
264265
}
@@ -468,7 +469,7 @@ collectMatchBitmap(RumBtreeData * btree, RumBtreeStack * stack,
468469
for (i = 0; i < RumGetNPosting(itup); i++)
469470
{
470471
ptr = rumDataPageLeafRead(ptr, scanEntry->attnum, &item.item,
471-
rumstate);
472+
false, rumstate);
472473
SCAN_ITEM_PUT_KEY(scanEntry, item, idatum, icategory);
473474
rum_tuplesort_putrumitem(scanEntry->matchSortstate, &item);
474475
}
@@ -674,7 +675,8 @@ startScanEntry(RumState * rumstate, RumScanEntry entry, Snapshot snapshot)
674675

675676
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
676677
{
677-
ptr = rumDataPageLeafRead(ptr, entry->attnum, &item, rumstate);
678+
ptr = rumDataPageLeafRead(ptr, entry->attnum, &item, true,
679+
rumstate);
678680
entry->list[i - FirstOffsetNumber] = item;
679681
}
680682

@@ -689,7 +691,7 @@ startScanEntry(RumState * rumstate, RumScanEntry entry, Snapshot snapshot)
689691
entry->predictNumberResult = entry->nlist;
690692
entry->list = (RumItem *) palloc(sizeof(RumItem) * entry->nlist);
691693

692-
rumReadTuple(rumstate, entry->attnum, itup, entry->list);
694+
rumReadTuple(rumstate, entry->attnum, itup, entry->list, true);
693695
entry->isFinished = setListPositionScanEntry(rumstate, entry);
694696
if (!entry->isFinished)
695697
entry->curItem = entry->list[entry->offset];
@@ -935,7 +937,8 @@ entryGetNextItem(RumState * rumstate, RumScanEntry entry, Snapshot snapshot)
935937

936938
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
937939
{
938-
ptr = rumDataPageLeafRead(ptr, entry->attnum, &item, rumstate);
940+
ptr = rumDataPageLeafRead(ptr, entry->attnum, &item, true,
941+
rumstate);
939942
entry->list[i - FirstOffsetNumber] = item;
940943

941944
if (searchBorder)
@@ -1091,7 +1094,8 @@ entryGetNextItemList(RumState * rumstate, RumScanEntry entry, Snapshot snapshot)
10911094

10921095
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
10931096
{
1094-
ptr = rumDataPageLeafRead(ptr, entry->attnum, &item, rumstate);
1097+
ptr = rumDataPageLeafRead(ptr, entry->attnum, &item, true,
1098+
rumstate);
10951099
entry->list[i - FirstOffsetNumber] = item;
10961100
}
10971101

@@ -1104,7 +1108,7 @@ entryGetNextItemList(RumState * rumstate, RumScanEntry entry, Snapshot snapshot)
11041108
entry->predictNumberResult = entry->nlist;
11051109
entry->list = (RumItem *) palloc(sizeof(RumItem) * entry->nlist);
11061110

1107-
rumReadTuple(rumstate, entry->attnum, itup, entry->list);
1111+
rumReadTuple(rumstate, entry->attnum, itup, entry->list, true);
11081112
entry->isFinished = setListPositionScanEntry(rumstate, entry);
11091113
}
11101114

@@ -1659,7 +1663,8 @@ scanPage(RumState * rumstate, RumScanEntry entry, RumItem *item, bool equalOk)
16591663
bound = -1;
16601664
for (i = first; i <= maxoff; i++)
16611665
{
1662-
ptr = rumDataPageLeafRead(ptr, entry->attnum, &iter_item, rumstate);
1666+
ptr = rumDataPageLeafRead(ptr, entry->attnum, &iter_item, true,
1667+
rumstate);
16631668
entry->list[i - first] = iter_item;
16641669

16651670
if (bound != -1)

src/ruminsert.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ addItemPointersToLeafTuple(RumState * rumstate,
272272
newNPosting = oldNPosting + nitem;
273273
newItems = (RumItem *) palloc(sizeof(RumItem) * newNPosting);
274274

275-
rumReadTuple(rumstate, attnum, old, oldItems);
275+
rumReadTuple(rumstate, attnum, old, oldItems, false);
276276

277277
newNPosting = rumMergeRumItems(rumstate, attnum, newItems,
278278
items, nitem, oldItems, oldNPosting);

src/rumvacuum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ rumVacuumPostingList(RumVacuumState * gvs, OffsetNumber attnum, Pointer src,
6363
for (i = 0; i < nitem; i++)
6464
{
6565
prev = ptr;
66-
ptr = rumDataPageLeafRead(ptr, attnum, &item, &gvs->rumstate);
66+
ptr = rumDataPageLeafRead(ptr, attnum, &item, false, &gvs->rumstate);
6767
if (gvs->callback(&item.iptr, gvs->callback_state))
6868
{
6969
gvs->result->tuples_removed += 1;

0 commit comments

Comments
 (0)