Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions

tstoreReceiver.c File Reference

#include "postgres.h"
#include "access/tuptoaster.h"
#include "executor/tstoreReceiver.h"
Include dependency graph for tstoreReceiver.c:

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)
DestReceiverCreateTuplestoreDestReceiver (void)
void SetTuplestoreDestReceiverParams (DestReceiver *self, Tuplestorestate *tStore, MemoryContext tContext, bool detoast)

Function Documentation

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]

Definition at line 178 of file tstoreReceiver.c.

References pfree().

{
    pfree(self);
}

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;
    }
}