#include "postgres.h"
#include "access/tuptoaster.h"
#include "executor/tstoreReceiver.h"
Go to the source code of this file.
Data Structures | |
struct | TStoreState |
Functions | |
static void | tstoreReceiveSlot_notoast (TupleTableSlot *slot, DestReceiver *self) |
static void | tstoreReceiveSlot_detoast (TupleTableSlot *slot, DestReceiver *self) |
static void | tstoreStartupReceiver (DestReceiver *self, int operation, TupleDesc typeinfo) |
static void | tstoreShutdownReceiver (DestReceiver *self) |
static void | tstoreDestroyReceiver (DestReceiver *self) |
DestReceiver * | CreateTuplestoreDestReceiver (void) |
void | SetTuplestoreDestReceiverParams (DestReceiver *self, Tuplestorestate *tStore, MemoryContext tContext, bool detoast) |
DestReceiver* CreateTuplestoreDestReceiver | ( | void | ) |
Definition at line 187 of file tstoreReceiver.c.
References palloc0().
Referenced by CreateDestReceiver().
{ TStoreState *self = (TStoreState *) palloc0(sizeof(TStoreState)); self->pub.receiveSlot = tstoreReceiveSlot_notoast; /* might change */ self->pub.rStartup = tstoreStartupReceiver; self->pub.rShutdown = tstoreShutdownReceiver; self->pub.rDestroy = tstoreDestroyReceiver; self->pub.mydest = DestTuplestore; /* private fields will be set by SetTuplestoreDestReceiverParams */ return (DestReceiver *) self; }
void SetTuplestoreDestReceiverParams | ( | DestReceiver * | self, | |
Tuplestorestate * | tStore, | |||
MemoryContext | tContext, | |||
bool | detoast | |||
) |
Definition at line 206 of file tstoreReceiver.c.
References Assert, TStoreState::cxt, DestTuplestore, TStoreState::detoast, _DestReceiver::mydest, TStoreState::pub, and TStoreState::tstore.
Referenced by FillPortalStore(), and PersistHoldablePortal().
{ TStoreState *myState = (TStoreState *) self; Assert(myState->pub.mydest == DestTuplestore); myState->tstore = tStore; myState->cxt = tContext; myState->detoast = detoast; }
static void tstoreDestroyReceiver | ( | DestReceiver * | self | ) | [static] |
static void tstoreReceiveSlot_detoast | ( | TupleTableSlot * | slot, | |
DestReceiver * | self | |||
) | [static] |
Definition at line 106 of file tstoreReceiver.c.
References tupleDesc::attrs, TStoreState::cxt, DatumGetPointer, heap_tuple_fetch_attr(), i, MemoryContextSwitchTo(), tupleDesc::natts, TStoreState::outvalues, pfree(), PointerGetDatum, slot_getallattrs(), TStoreState::tofree, TStoreState::tstore, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, tuplestore_putvalues(), val, and VARATT_IS_EXTERNAL.
{ TStoreState *myState = (TStoreState *) self; TupleDesc typeinfo = slot->tts_tupleDescriptor; Form_pg_attribute *attrs = typeinfo->attrs; int natts = typeinfo->natts; int nfree; int i; MemoryContext oldcxt; /* Make sure the tuple is fully deconstructed */ slot_getallattrs(slot); /* * Fetch back any out-of-line datums. We build the new datums array in * myState->outvalues[] (but we can re-use the slot's isnull array). Also, * remember the fetched values to free afterwards. */ nfree = 0; for (i = 0; i < natts; i++) { Datum val = slot->tts_values[i]; if (!attrs[i]->attisdropped && attrs[i]->attlen == -1 && !slot->tts_isnull[i]) { if (VARATT_IS_EXTERNAL(DatumGetPointer(val))) { val = PointerGetDatum(heap_tuple_fetch_attr((struct varlena *) DatumGetPointer(val))); myState->tofree[nfree++] = val; } } myState->outvalues[i] = val; } /* * Push the modified tuple into the tuplestore. */ oldcxt = MemoryContextSwitchTo(myState->cxt); tuplestore_putvalues(myState->tstore, typeinfo, myState->outvalues, slot->tts_isnull); MemoryContextSwitchTo(oldcxt); /* And release any temporary detoasted values */ for (i = 0; i < nfree; i++) pfree(DatumGetPointer(myState->tofree[i])); }
static void tstoreReceiveSlot_notoast | ( | TupleTableSlot * | slot, | |
DestReceiver * | self | |||
) | [static] |
Definition at line 94 of file tstoreReceiver.c.
References TStoreState::tstore, and tuplestore_puttupleslot().
{ TStoreState *myState = (TStoreState *) self; tuplestore_puttupleslot(myState->tstore, slot); }
static void tstoreShutdownReceiver | ( | DestReceiver * | self | ) | [static] |
Definition at line 161 of file tstoreReceiver.c.
References TStoreState::outvalues, pfree(), and TStoreState::tofree.
{ TStoreState *myState = (TStoreState *) self; /* Release workspace if any */ if (myState->outvalues) pfree(myState->outvalues); myState->outvalues = NULL; if (myState->tofree) pfree(myState->tofree); myState->tofree = NULL; }
static void tstoreStartupReceiver | ( | DestReceiver * | self, | |
int | operation, | |||
TupleDesc | typeinfo | |||
) | [static] |
Definition at line 48 of file tstoreReceiver.c.
References tupleDesc::attrs, TStoreState::cxt, TStoreState::detoast, i, MemoryContextAlloc(), tupleDesc::natts, TStoreState::outvalues, TStoreState::pub, _DestReceiver::receiveSlot, and TStoreState::tofree.
{ TStoreState *myState = (TStoreState *) self; bool needtoast = false; Form_pg_attribute *attrs = typeinfo->attrs; int natts = typeinfo->natts; int i; /* Check if any columns require detoast work */ if (myState->detoast) { for (i = 0; i < natts; i++) { if (attrs[i]->attisdropped) continue; if (attrs[i]->attlen == -1) { needtoast = true; break; } } } /* Set up appropriate callback */ if (needtoast) { myState->pub.receiveSlot = tstoreReceiveSlot_detoast; /* Create workspace */ myState->outvalues = (Datum *) MemoryContextAlloc(myState->cxt, natts * sizeof(Datum)); myState->tofree = (Datum *) MemoryContextAlloc(myState->cxt, natts * sizeof(Datum)); } else { myState->pub.receiveSlot = tstoreReceiveSlot_notoast; myState->outvalues = NULL; myState->tofree = NULL; } }