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.
This commit is contained in:
Heikki Linnakangas 2019-06-06 09:46:52 +03:00
parent 6c0c283837
commit cd96389d71
2 changed files with 17 additions and 5 deletions

View File

@ -166,10 +166,10 @@ IndexOnlyNext(IndexOnlyScanState *node)
* Rats, we have to visit the heap to check visibility.
*/
InstrCountTuples2(node, 1);
if (!index_fetch_heap(scandesc, slot))
if (!index_fetch_heap(scandesc, node->ioss_TableSlot))
continue; /* no visible tuple, try next index entry */
ExecClearTuple(slot);
ExecClearTuple(node->ioss_TableSlot);
/*
* Only MVCC snapshots are supported here, so there should be no
@ -528,7 +528,17 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
*/
tupDesc = ExecTypeFromTL(node->indextlist);
ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc,
table_slot_callbacks(currentRelation));
&TTSOpsVirtual);
/*
* We need another slot, in a format that's suitable for the table AM,
* for when we need to fetch a tuple from the table for rechecking
* visibility.
*/
indexstate->ioss_TableSlot =
ExecAllocTableSlot(&estate->es_tupleTable,
RelationGetDescr(currentRelation),
table_slot_callbacks(currentRelation));
/*
* Initialize result type and projection info. The node's targetlist will

View File

@ -1359,7 +1359,7 @@ typedef struct
* SortSupport for reordering ORDER BY exprs
* OrderByTypByVals is the datatype of order by expression pass-by-value?
* OrderByTypLens typlens of the datatypes of order by expressions
* pscan_len size of parallel index scan descriptor
* PscanLen size of parallel index scan descriptor
* ----------------
*/
typedef struct IndexScanState
@ -1403,8 +1403,9 @@ typedef struct IndexScanState
* RuntimeContext expr context for evaling runtime Skeys
* RelationDesc index relation descriptor
* ScanDesc index scan descriptor
* TableSlot slot for holding tuples fetched from the table
* VMBuffer buffer in use for visibility map testing, if any
* ioss_PscanLen Size of parallel index-only scan descriptor
* PscanLen size of parallel index-only scan descriptor
* ----------------
*/
typedef struct IndexOnlyScanState
@ -1421,6 +1422,7 @@ typedef struct IndexOnlyScanState
ExprContext *ioss_RuntimeContext;
Relation ioss_RelationDesc;
struct IndexScanDescData *ioss_ScanDesc;
TupleTableSlot *ioss_TableSlot;
Buffer ioss_VMBuffer;
Size ioss_PscanLen;
} IndexOnlyScanState;