From: Andres Freund Date: Mon, 3 Dec 2018 20:56:23 +0000 (-0800) Subject: WIP: Fix tuple extension logic. X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=8c4abacbe4bfe2ae5435ed6ac5c30b2e6b6eed11;p=users%2Fandresfreund%2Fpostgres.git WIP: Fix tuple extension logic. Author: Reviewed-By: Discussion: https://postgr.es/m/ Backpatch: --- diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 37c46543cd..ac5d76bd41 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -394,6 +394,27 @@ tts_heap_get_heap_tuple(TupleTableSlot *slot) Assert(!TTS_EMPTY(slot)); if (!hslot->tuple) tts_heap_materialize(slot); + else if (HeapTupleHeaderGetNatts(hslot->tuple->t_data) + < slot->tts_tupleDescriptor->natts) + { + MemoryContext oldContext; + HeapTuple oldtuple; + + oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + + oldtuple = hslot->tuple; + hslot->tuple = heap_expand_tuple(hslot->tuple, + slot->tts_tupleDescriptor); + MemoryContextSwitchTo(oldContext); + + if (slot->tts_flags & TTS_FLAG_SHOULDFREE) + heap_freetuple(oldtuple); + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + + slot->tts_nvalid = 0; + hslot->off = 0; + slot_getallattrs(slot); + } return hslot->tuple; } @@ -762,6 +783,33 @@ tts_buffer_heap_get_heap_tuple(TupleTableSlot *slot) if (!bslot->base.tuple) tts_buffer_heap_materialize(slot); + else if (HeapTupleHeaderGetNatts(bslot->base.tuple->t_data) + < slot->tts_tupleDescriptor->natts) + { + MemoryContext oldContext; + HeapTuple oldtuple; + + oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + + oldtuple = bslot->base.tuple; + bslot->base.tuple = heap_expand_tuple(bslot->base.tuple, + slot->tts_tupleDescriptor); + MemoryContextSwitchTo(oldContext); + + if (slot->tts_flags & TTS_FLAG_SHOULDFREE) + heap_freetuple(oldtuple); + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + + if (BufferIsValid(bslot->buffer)) + { + ReleaseBuffer(bslot->buffer); + bslot->buffer = InvalidBuffer; + } + + slot->tts_nvalid = 0; + bslot->base.off = 0; + slot_getallattrs(slot); + } return bslot->base.tuple; }