aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2019-06-06 09:46:52 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2019-06-06 09:46:52 +0300
commitcd96389d713787b025c84869ba417c6f2f008a86 (patch)
treedec68fd47e5d6bf7e94185607d12bf2ce9afc3dd /src/backend/executor
parent6c0c28383749c0ade89ac70ba6dbce9af140c0a9 (diff)
downloadpostgresql-cd96389d713787b025c84869ba417c6f2f008a86.tar.gz
postgresql-cd96389d713787b025c84869ba417c6f2f008a86.zip
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.
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/nodeIndexonlyscan.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index ee5b1c493b7..8a4d795d1a9 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -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