Skip to content

Commit cd96389

Browse files
committed
Fix confusion on different kinds of slots in IndexOnlyScans.
We used the same slot to store a tuple from the index, and to store a tuple from the table. That's not OK. It worked with the heap, because heapam_getnextslot() stores a HeapTuple to the slot, and doesn't care how large the tts_values/nulls arrays are. But when I played with a toy table AM implementation that used a virtual tuple, it caused memory overruns. In the passing, tidy up comments on the ioss_PscanLen fields.
1 parent 6c0c283 commit cd96389

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

src/backend/executor/nodeIndexonlyscan.c

+13-3
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ IndexOnlyNext(IndexOnlyScanState *node)
166166
* Rats, we have to visit the heap to check visibility.
167167
*/
168168
InstrCountTuples2(node, 1);
169-
if (!index_fetch_heap(scandesc, slot))
169+
if (!index_fetch_heap(scandesc, node->ioss_TableSlot))
170170
continue; /* no visible tuple, try next index entry */
171171

172-
ExecClearTuple(slot);
172+
ExecClearTuple(node->ioss_TableSlot);
173173

174174
/*
175175
* Only MVCC snapshots are supported here, so there should be no
@@ -528,7 +528,17 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
528528
*/
529529
tupDesc = ExecTypeFromTL(node->indextlist);
530530
ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc,
531-
table_slot_callbacks(currentRelation));
531+
&TTSOpsVirtual);
532+
533+
/*
534+
* We need another slot, in a format that's suitable for the table AM,
535+
* for when we need to fetch a tuple from the table for rechecking
536+
* visibility.
537+
*/
538+
indexstate->ioss_TableSlot =
539+
ExecAllocTableSlot(&estate->es_tupleTable,
540+
RelationGetDescr(currentRelation),
541+
table_slot_callbacks(currentRelation));
532542

533543
/*
534544
* Initialize result type and projection info. The node's targetlist will

src/include/nodes/execnodes.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ typedef struct
13591359
* SortSupport for reordering ORDER BY exprs
13601360
* OrderByTypByVals is the datatype of order by expression pass-by-value?
13611361
* OrderByTypLens typlens of the datatypes of order by expressions
1362-
* pscan_len size of parallel index scan descriptor
1362+
* PscanLen size of parallel index scan descriptor
13631363
* ----------------
13641364
*/
13651365
typedef struct IndexScanState
@@ -1403,8 +1403,9 @@ typedef struct IndexScanState
14031403
* RuntimeContext expr context for evaling runtime Skeys
14041404
* RelationDesc index relation descriptor
14051405
* ScanDesc index scan descriptor
1406+
* TableSlot slot for holding tuples fetched from the table
14061407
* VMBuffer buffer in use for visibility map testing, if any
1407-
* ioss_PscanLen Size of parallel index-only scan descriptor
1408+
* PscanLen size of parallel index-only scan descriptor
14081409
* ----------------
14091410
*/
14101411
typedef struct IndexOnlyScanState
@@ -1421,6 +1422,7 @@ typedef struct IndexOnlyScanState
14211422
ExprContext *ioss_RuntimeContext;
14221423
Relation ioss_RelationDesc;
14231424
struct IndexScanDescData *ioss_ScanDesc;
1425+
TupleTableSlot *ioss_TableSlot;
14241426
Buffer ioss_VMBuffer;
14251427
Size ioss_PscanLen;
14261428
} IndexOnlyScanState;

0 commit comments

Comments
 (0)