PostgreSQL Source Code  git master
tstoreReceiver.c File Reference
#include "postgres.h"
#include "access/detoast.h"
#include "access/tupconvert.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 bool tstoreReceiveSlot_notoast (TupleTableSlot *slot, DestReceiver *self)
 
static bool tstoreReceiveSlot_detoast (TupleTableSlot *slot, DestReceiver *self)
 
static bool tstoreReceiveSlot_tupmap (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, TupleDesc target_tupdesc, const char *map_failure_msg)
 

Function Documentation

◆ CreateTuplestoreDestReceiver()

DestReceiver* CreateTuplestoreDestReceiver ( void  )

Definition at line 238 of file tstoreReceiver.c.

References DestTuplestore, palloc0(), tstoreDestroyReceiver(), tstoreReceiveSlot_notoast(), tstoreShutdownReceiver(), and tstoreStartupReceiver().

Referenced by CreateDestReceiver().

239 {
240  TStoreState *self = (TStoreState *) palloc0(sizeof(TStoreState));
241 
242  self->pub.receiveSlot = tstoreReceiveSlot_notoast; /* might change */
243  self->pub.rStartup = tstoreStartupReceiver;
244  self->pub.rShutdown = tstoreShutdownReceiver;
245  self->pub.rDestroy = tstoreDestroyReceiver;
246  self->pub.mydest = DestTuplestore;
247 
248  /* private fields will be set by SetTuplestoreDestReceiverParams */
249 
250  return (DestReceiver *) self;
251 }
static void tstoreShutdownReceiver(DestReceiver *self)
static bool tstoreReceiveSlot_notoast(TupleTableSlot *slot, DestReceiver *self)
static void tstoreStartupReceiver(DestReceiver *self, int operation, TupleDesc typeinfo)
void * palloc0(Size size)
Definition: mcxt.c:980
static void tstoreDestroyReceiver(DestReceiver *self)

◆ SetTuplestoreDestReceiverParams()

void SetTuplestoreDestReceiverParams ( DestReceiver self,
Tuplestorestate tStore,
MemoryContext  tContext,
bool  detoast,
TupleDesc  target_tupdesc,
const char *  map_failure_msg 
)

Definition at line 266 of file tstoreReceiver.c.

References Assert, TStoreState::cxt, DestTuplestore, TStoreState::detoast, TStoreState::map_failure_msg, _DestReceiver::mydest, TStoreState::pub, TStoreState::target_tupdesc, and TStoreState::tstore.

Referenced by exec_stmt_return_query(), FillPortalStore(), and PersistHoldablePortal().

272 {
273  TStoreState *myState = (TStoreState *) self;
274 
275  Assert(!(detoast && target_tupdesc));
276 
277  Assert(myState->pub.mydest == DestTuplestore);
278  myState->tstore = tStore;
279  myState->cxt = tContext;
280  myState->detoast = detoast;
281  myState->target_tupdesc = target_tupdesc;
282  myState->map_failure_msg = map_failure_msg;
283 }
MemoryContext cxt
CommandDest mydest
Definition: dest.h:129
DestReceiver pub
Tuplestorestate * tstore
TupleDesc target_tupdesc
#define Assert(condition)
Definition: c.h:745
const char * map_failure_msg

◆ tstoreDestroyReceiver()

static void tstoreDestroyReceiver ( DestReceiver self)
static

Definition at line 229 of file tstoreReceiver.c.

References pfree().

Referenced by CreateTuplestoreDestReceiver().

230 {
231  pfree(self);
232 }
void pfree(void *pointer)
Definition: mcxt.c:1056

◆ tstoreReceiveSlot_detoast()

static bool tstoreReceiveSlot_detoast ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 136 of file tstoreReceiver.c.

References TStoreState::cxt, DatumGetPointer, detoast_external_attr(), i, MemoryContextSwitchTo(), TupleDescData::natts, TStoreState::outvalues, pfree(), PointerGetDatum, slot_getallattrs(), TStoreState::tofree, TStoreState::tstore, TupleTableSlot::tts_isnull, TupleTableSlot::tts_tupleDescriptor, TupleTableSlot::tts_values, TupleDescAttr, tuplestore_putvalues(), val, and VARATT_IS_EXTERNAL.

Referenced by tstoreStartupReceiver().

137 {
138  TStoreState *myState = (TStoreState *) self;
139  TupleDesc typeinfo = slot->tts_tupleDescriptor;
140  int natts = typeinfo->natts;
141  int nfree;
142  int i;
143  MemoryContext oldcxt;
144 
145  /* Make sure the tuple is fully deconstructed */
146  slot_getallattrs(slot);
147 
148  /*
149  * Fetch back any out-of-line datums. We build the new datums array in
150  * myState->outvalues[] (but we can re-use the slot's isnull array). Also,
151  * remember the fetched values to free afterwards.
152  */
153  nfree = 0;
154  for (i = 0; i < natts; i++)
155  {
156  Datum val = slot->tts_values[i];
157  Form_pg_attribute attr = TupleDescAttr(typeinfo, i);
158 
159  if (!attr->attisdropped && attr->attlen == -1 && !slot->tts_isnull[i])
160  {
162  {
164  DatumGetPointer(val)));
165  myState->tofree[nfree++] = val;
166  }
167  }
168 
169  myState->outvalues[i] = val;
170  }
171 
172  /*
173  * Push the modified tuple into the tuplestore.
174  */
175  oldcxt = MemoryContextSwitchTo(myState->cxt);
176  tuplestore_putvalues(myState->tstore, typeinfo,
177  myState->outvalues, slot->tts_isnull);
178  MemoryContextSwitchTo(oldcxt);
179 
180  /* And release any temporary detoasted values */
181  for (i = 0; i < nfree; i++)
182  pfree(DatumGetPointer(myState->tofree[i]));
183 
184  return true;
185 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
Datum * tofree
#define PointerGetDatum(X)
Definition: postgres.h:556
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
MemoryContext cxt
struct varlena * detoast_external_attr(struct varlena *attr)
Definition: detoast.c:44
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
Datum * tts_values
Definition: tuptable.h:126
#define VARATT_IS_EXTERNAL(PTR)
Definition: postgres.h:313
void pfree(void *pointer)
Definition: mcxt.c:1056
Tuplestorestate * tstore
static void slot_getallattrs(TupleTableSlot *slot)
Definition: tuptable.h:354
bool * tts_isnull
Definition: tuptable.h:128
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
uintptr_t Datum
Definition: postgres.h:367
#define DatumGetPointer(X)
Definition: postgres.h:549
Datum * outvalues
int i
Definition: c.h:562
long val
Definition: informix.c:664

◆ tstoreReceiveSlot_notoast()

static bool tstoreReceiveSlot_notoast ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 122 of file tstoreReceiver.c.

References TStoreState::tstore, and tuplestore_puttupleslot().

Referenced by CreateTuplestoreDestReceiver(), and tstoreStartupReceiver().

123 {
124  TStoreState *myState = (TStoreState *) self;
125 
126  tuplestore_puttupleslot(myState->tstore, slot);
127 
128  return true;
129 }
void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)
Definition: tuplestore.c:708
Tuplestorestate * tstore

◆ tstoreReceiveSlot_tupmap()

static bool tstoreReceiveSlot_tupmap ( TupleTableSlot slot,
DestReceiver self 
)
static

Definition at line 192 of file tstoreReceiver.c.

References TupleConversionMap::attrMap, execute_attr_map_slot(), TStoreState::mapslot, TStoreState::tstore, tuplestore_puttupleslot(), and TStoreState::tupmap.

Referenced by tstoreStartupReceiver().

193 {
194  TStoreState *myState = (TStoreState *) self;
195 
196  execute_attr_map_slot(myState->tupmap->attrMap, slot, myState->mapslot);
197  tuplestore_puttupleslot(myState->tstore, myState->mapslot);
198 
199  return true;
200 }
void tuplestore_puttupleslot(Tuplestorestate *state, TupleTableSlot *slot)
Definition: tuplestore.c:708
TupleConversionMap * tupmap
Tuplestorestate * tstore
AttrMap * attrMap
Definition: tupconvert.h:27
TupleTableSlot * mapslot
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition: tupconvert.c:177

◆ tstoreShutdownReceiver()

static void tstoreShutdownReceiver ( DestReceiver self)
static

Definition at line 206 of file tstoreReceiver.c.

References ExecDropSingleTupleTableSlot(), free_conversion_map(), TStoreState::mapslot, TStoreState::outvalues, pfree(), TStoreState::tofree, and TStoreState::tupmap.

Referenced by CreateTuplestoreDestReceiver().

207 {
208  TStoreState *myState = (TStoreState *) self;
209 
210  /* Release workspace if any */
211  if (myState->outvalues)
212  pfree(myState->outvalues);
213  myState->outvalues = NULL;
214  if (myState->tofree)
215  pfree(myState->tofree);
216  myState->tofree = NULL;
217  if (myState->tupmap)
218  free_conversion_map(myState->tupmap);
219  myState->tupmap = NULL;
220  if (myState->mapslot)
222  myState->mapslot = NULL;
223 }
Datum * tofree
TupleConversionMap * tupmap
void pfree(void *pointer)
Definition: mcxt.c:1056
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
void free_conversion_map(TupleConversionMap *map)
Definition: tupconvert.c:233
TupleTableSlot * mapslot
Datum * outvalues

◆ tstoreStartupReceiver()

static void tstoreStartupReceiver ( DestReceiver self,
int  operation,
TupleDesc  typeinfo 
)
static

Definition at line 56 of file tstoreReceiver.c.

References Assert, convert_tuples_by_position(), TStoreState::cxt, TStoreState::detoast, i, MakeSingleTupleTableSlot(), TStoreState::map_failure_msg, TStoreState::mapslot, MemoryContextAlloc(), TupleDescData::natts, TStoreState::outvalues, TStoreState::pub, _DestReceiver::receiveSlot, TStoreState::target_tupdesc, TStoreState::tofree, tstoreReceiveSlot_detoast(), tstoreReceiveSlot_notoast(), tstoreReceiveSlot_tupmap(), TTSOpsVirtual, TupleDescAttr, and TStoreState::tupmap.

Referenced by CreateTuplestoreDestReceiver().

57 {
58  TStoreState *myState = (TStoreState *) self;
59  bool needtoast = false;
60  int natts = typeinfo->natts;
61  int i;
62 
63  /* Check if any columns require detoast work */
64  if (myState->detoast)
65  {
66  for (i = 0; i < natts; i++)
67  {
68  Form_pg_attribute attr = TupleDescAttr(typeinfo, i);
69 
70  if (attr->attisdropped)
71  continue;
72  if (attr->attlen == -1)
73  {
74  needtoast = true;
75  break;
76  }
77  }
78  }
79 
80  /* Check if tuple conversion is needed */
81  if (myState->target_tupdesc)
82  myState->tupmap = convert_tuples_by_position(typeinfo,
83  myState->target_tupdesc,
84  myState->map_failure_msg);
85  else
86  myState->tupmap = NULL;
87 
88  /* Set up appropriate callback */
89  if (needtoast)
90  {
91  Assert(!myState->tupmap);
93  /* Create workspace */
94  myState->outvalues = (Datum *)
95  MemoryContextAlloc(myState->cxt, natts * sizeof(Datum));
96  myState->tofree = (Datum *)
97  MemoryContextAlloc(myState->cxt, natts * sizeof(Datum));
98  myState->mapslot = NULL;
99  }
100  else if (myState->tupmap)
101  {
103  myState->outvalues = NULL;
104  myState->tofree = NULL;
105  myState->mapslot = MakeSingleTupleTableSlot(myState->target_tupdesc,
106  &TTSOpsVirtual);
107  }
108  else
109  {
111  myState->outvalues = NULL;
112  myState->tofree = NULL;
113  myState->mapslot = NULL;
114  }
115 }
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:119
Datum * tofree
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1208
TupleConversionMap * convert_tuples_by_position(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:59
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
MemoryContext cxt
const TupleTableSlotOps TTSOpsVirtual
Definition: execTuples.c:83
TupleConversionMap * tupmap
DestReceiver pub
static bool tstoreReceiveSlot_notoast(TupleTableSlot *slot, DestReceiver *self)
TupleDesc target_tupdesc
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
TupleTableSlot * mapslot
uintptr_t Datum
Definition: postgres.h:367
#define Assert(condition)
Definition: c.h:745
static bool tstoreReceiveSlot_detoast(TupleTableSlot *slot, DestReceiver *self)
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
Datum * outvalues
int i
static bool tstoreReceiveSlot_tupmap(TupleTableSlot *slot, DestReceiver *self)
const char * map_failure_msg