PostgreSQL Source Code  git master
execTuples.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * execTuples.c
4  * Routines dealing with TupleTableSlots. These are used for resource
5  * management associated with tuples (eg, releasing buffer pins for
6  * tuples in disk buffers, or freeing the memory occupied by transient
7  * tuples). Slots also provide access abstraction that lets us implement
8  * "virtual" tuples to reduce data-copying overhead.
9  *
10  * Routines dealing with the type information for tuples. Currently,
11  * the type information for a tuple is an array of FormData_pg_attribute.
12  * This information is needed by routines manipulating tuples
13  * (getattribute, formtuple, etc.).
14  *
15  * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
16  * Portions Copyright (c) 1994, Regents of the University of California
17  *
18  *
19  * IDENTIFICATION
20  * src/backend/executor/execTuples.c
21  *
22  *-------------------------------------------------------------------------
23  */
24 /*
25  * INTERFACE ROUTINES
26  *
27  * SLOT CREATION/DESTRUCTION
28  * MakeTupleTableSlot - create an empty slot
29  * ExecAllocTableSlot - create a slot within a tuple table
30  * ExecResetTupleTable - clear and optionally delete a tuple table
31  * MakeSingleTupleTableSlot - make a standalone slot, set its descriptor
32  * ExecDropSingleTupleTableSlot - destroy a standalone slot
33  *
34  * SLOT ACCESSORS
35  * ExecSetSlotDescriptor - set a slot's tuple descriptor
36  * ExecStoreTuple - store a physical tuple in the slot
37  * ExecStoreMinimalTuple - store a minimal physical tuple in the slot
38  * ExecClearTuple - clear contents of a slot
39  * ExecStoreVirtualTuple - mark slot as containing a virtual tuple
40  * ExecCopySlotTuple - build a physical tuple from a slot
41  * ExecCopySlotMinimalTuple - build a minimal physical tuple from a slot
42  * ExecMaterializeSlot - convert virtual to physical storage
43  * ExecCopySlot - copy one slot's contents to another
44  *
45  * CONVENIENCE INITIALIZATION ROUTINES
46  * ExecInitResultTupleSlot \ convenience routines to initialize
47  * ExecInitScanTupleSlot \ the various tuple slots for nodes
48  * ExecInitExtraTupleSlot / which store copies of tuples.
49  * ExecInitNullTupleSlot /
50  *
51  * Routines that probably belong somewhere else:
52  * ExecTypeFromTL - form a TupleDesc from a target list
53  *
54  * EXAMPLE OF HOW TABLE ROUTINES WORK
55  * Suppose we have a query such as SELECT emp.name FROM emp and we have
56  * a single SeqScan node in the query plan.
57  *
58  * At ExecutorStart()
59  * ----------------
60  * - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
61  * ExecInitResultTupleSlotTL() to construct TupleTableSlots
62  * for the tuples returned by the access methods and the
63  * tuples resulting from performing target list projections.
64  *
65  * During ExecutorRun()
66  * ----------------
67  * - SeqNext() calls ExecStoreTuple() to place the tuple returned
68  * by the access methods into the scan tuple slot.
69  *
70  * - ExecSeqScan() calls ExecStoreTuple() to take the result
71  * tuple from ExecProject() and place it into the result tuple slot.
72  *
73  * - ExecutePlan() calls the output function.
74  *
75  * The important thing to watch in the executor code is how pointers
76  * to the slots containing tuples are passed instead of the tuples
77  * themselves. This facilitates the communication of related information
78  * (such as whether or not a tuple should be pfreed, what buffer contains
79  * this tuple, the tuple's tuple descriptor, etc). It also allows us
80  * to avoid physically constructing projection tuples in many cases.
81  */
82 #include "postgres.h"
83 
84 #include "access/htup_details.h"
85 #include "access/tuptoaster.h"
86 #include "funcapi.h"
87 #include "catalog/pg_type.h"
88 #include "nodes/nodeFuncs.h"
89 #include "storage/bufmgr.h"
90 #include "utils/builtins.h"
91 #include "utils/lsyscache.h"
92 #include "utils/typcache.h"
93 
94 
95 static TupleDesc ExecTypeFromTLInternal(List *targetList,
96  bool hasoid, bool skipjunk);
97 
98 
99 /* ----------------------------------------------------------------
100  * tuple table create/delete functions
101  * ----------------------------------------------------------------
102  */
103 
104 /* --------------------------------
105  * MakeTupleTableSlot
106  *
107  * Basic routine to make an empty TupleTableSlot. If tupleDesc is
108  * specified the slot's descriptor is fixed for it's lifetime, gaining
109  * some efficiency. If that's undesirable, pass NULL.
110  * --------------------------------
111  */
114 {
115  Size sz;
116  TupleTableSlot *slot;
117 
118  /*
119  * When a fixed descriptor is specified, we can reduce overhead by
120  * allocating the entire slot in one go.
121  */
122  if (tupleDesc)
123  sz = MAXALIGN(sizeof(TupleTableSlot)) +
124  MAXALIGN(tupleDesc->natts * sizeof(Datum)) +
125  MAXALIGN(tupleDesc->natts * sizeof(bool));
126  else
127  sz = sizeof(TupleTableSlot);
128 
129  slot = palloc0(sz);
130  slot->type = T_TupleTableSlot;
131  slot->tts_isempty = true;
132  slot->tts_shouldFree = false;
133  slot->tts_shouldFreeMin = false;
134  slot->tts_tuple = NULL;
135  slot->tts_fixedTupleDescriptor = tupleDesc != NULL;
136  slot->tts_tupleDescriptor = tupleDesc;
138  slot->tts_buffer = InvalidBuffer;
139  slot->tts_nvalid = 0;
140  slot->tts_values = NULL;
141  slot->tts_isnull = NULL;
142  slot->tts_mintuple = NULL;
143 
144  if (tupleDesc != NULL)
145  {
146  slot->tts_values = (Datum *)
147  (((char *) slot)
148  + MAXALIGN(sizeof(TupleTableSlot)));
149  slot->tts_isnull = (bool *)
150  (((char *) slot)
151  + MAXALIGN(sizeof(TupleTableSlot))
152  + MAXALIGN(tupleDesc->natts * sizeof(Datum)));
153 
154  PinTupleDesc(tupleDesc);
155  }
156 
157  return slot;
158 }
159 
160 /* --------------------------------
161  * ExecAllocTableSlot
162  *
163  * Create a tuple table slot within a tuple table (which is just a List).
164  * --------------------------------
165  */
167 ExecAllocTableSlot(List **tupleTable, TupleDesc desc)
168 {
169  TupleTableSlot *slot = MakeTupleTableSlot(desc);
170 
171  *tupleTable = lappend(*tupleTable, slot);
172 
173  return slot;
174 }
175 
176 /* --------------------------------
177  * ExecResetTupleTable
178  *
179  * This releases any resources (buffer pins, tupdesc refcounts)
180  * held by the tuple table, and optionally releases the memory
181  * occupied by the tuple table data structure.
182  * It is expected that this routine be called by EndPlan().
183  * --------------------------------
184  */
185 void
186 ExecResetTupleTable(List *tupleTable, /* tuple table */
187  bool shouldFree) /* true if we should free memory */
188 {
189  ListCell *lc;
190 
191  foreach(lc, tupleTable)
192  {
194 
195  /* Always release resources and reset the slot to empty */
196  ExecClearTuple(slot);
197  if (slot->tts_tupleDescriptor)
198  {
200  slot->tts_tupleDescriptor = NULL;
201  }
202 
203  /* If shouldFree, release memory occupied by the slot itself */
204  if (shouldFree)
205  {
206  if (!slot->tts_fixedTupleDescriptor)
207  {
208  if (slot->tts_values)
209  pfree(slot->tts_values);
210  if (slot->tts_isnull)
211  pfree(slot->tts_isnull);
212  }
213  pfree(slot);
214  }
215  }
216 
217  /* If shouldFree, release the list structure */
218  if (shouldFree)
219  list_free(tupleTable);
220 }
221 
222 /* --------------------------------
223  * MakeSingleTupleTableSlot
224  *
225  * This is a convenience routine for operations that need a
226  * standalone TupleTableSlot not gotten from the main executor
227  * tuple table. It makes a single slot and initializes it
228  * to use the given tuple descriptor.
229  * --------------------------------
230  */
233 {
234  TupleTableSlot *slot = MakeTupleTableSlot(tupdesc);
235 
236  return slot;
237 }
238 
239 /* --------------------------------
240  * ExecDropSingleTupleTableSlot
241  *
242  * Release a TupleTableSlot made with MakeSingleTupleTableSlot.
243  * DON'T use this on a slot that's part of a tuple table list!
244  * --------------------------------
245  */
246 void
248 {
249  /* This should match ExecResetTupleTable's processing of one slot */
250  Assert(IsA(slot, TupleTableSlot));
251  ExecClearTuple(slot);
252  if (slot->tts_tupleDescriptor)
254  if (!slot->tts_fixedTupleDescriptor)
255  {
256  if (slot->tts_values)
257  pfree(slot->tts_values);
258  if (slot->tts_isnull)
259  pfree(slot->tts_isnull);
260  }
261  pfree(slot);
262 }
263 
264 
265 /* ----------------------------------------------------------------
266  * tuple table slot accessor functions
267  * ----------------------------------------------------------------
268  */
269 
270 /* --------------------------------
271  * ExecSetSlotDescriptor
272  *
273  * This function is used to set the tuple descriptor associated
274  * with the slot's tuple. The passed descriptor must have lifespan
275  * at least equal to the slot's. If it is a reference-counted descriptor
276  * then the reference count is incremented for as long as the slot holds
277  * a reference.
278  * --------------------------------
279  */
280 void
281 ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
282  TupleDesc tupdesc) /* new tuple descriptor */
283 {
285 
286  /* For safety, make sure slot is empty before changing it */
287  ExecClearTuple(slot);
288 
289  /*
290  * Release any old descriptor. Also release old Datum/isnull arrays if
291  * present (we don't bother to check if they could be re-used).
292  */
293  if (slot->tts_tupleDescriptor)
295 
296  if (slot->tts_values)
297  pfree(slot->tts_values);
298  if (slot->tts_isnull)
299  pfree(slot->tts_isnull);
300 
301  /*
302  * Install the new descriptor; if it's refcounted, bump its refcount.
303  */
304  slot->tts_tupleDescriptor = tupdesc;
305  PinTupleDesc(tupdesc);
306 
307  /*
308  * Allocate Datum/isnull arrays of the appropriate size. These must have
309  * the same lifetime as the slot, so allocate in the slot's own context.
310  */
311  slot->tts_values = (Datum *)
312  MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(Datum));
313  slot->tts_isnull = (bool *)
314  MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(bool));
315 }
316 
317 /* --------------------------------
318  * ExecStoreTuple
319  *
320  * This function is used to store a physical tuple into a specified
321  * slot in the tuple table.
322  *
323  * tuple: tuple to store
324  * slot: slot to store it in
325  * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer
326  * shouldFree: true if ExecClearTuple should pfree() the tuple
327  * when done with it
328  *
329  * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin
330  * on the buffer which is held until the slot is cleared, so that the tuple
331  * won't go away on us.
332  *
333  * shouldFree is normally set 'true' for tuples constructed on-the-fly.
334  * It must always be 'false' for tuples that are stored in disk pages,
335  * since we don't want to try to pfree those.
336  *
337  * Another case where it is 'false' is when the referenced tuple is held
338  * in a tuple table slot belonging to a lower-level executor Proc node.
339  * In this case the lower-level slot retains ownership and responsibility
340  * for eventually releasing the tuple. When this method is used, we must
341  * be certain that the upper-level Proc node will lose interest in the tuple
342  * sooner than the lower-level one does! If you're not certain, copy the
343  * lower-level tuple with heap_copytuple and let the upper-level table
344  * slot assume ownership of the copy!
345  *
346  * Return value is just the passed-in slot pointer.
347  *
348  * NOTE: before PostgreSQL 8.1, this function would accept a NULL tuple
349  * pointer and effectively behave like ExecClearTuple (though you could
350  * still specify a buffer to pin, which would be an odd combination).
351  * This saved a couple lines of code in a few places, but seemed more likely
352  * to mask logic errors than to be really useful, so it's now disallowed.
353  * --------------------------------
354  */
357  TupleTableSlot *slot,
358  Buffer buffer,
359  bool shouldFree)
360 {
361  /*
362  * sanity checks
363  */
364  Assert(tuple != NULL);
365  Assert(slot != NULL);
366  Assert(slot->tts_tupleDescriptor != NULL);
367  /* passing shouldFree=true for a tuple on a disk page is not sane */
368  Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
369 
370  /*
371  * Free any old physical tuple belonging to the slot.
372  */
373  if (slot->tts_shouldFree)
374  heap_freetuple(slot->tts_tuple);
375  if (slot->tts_shouldFreeMin)
377 
378  /*
379  * Store the new tuple into the specified slot.
380  */
381  slot->tts_isempty = false;
382  slot->tts_shouldFree = shouldFree;
383  slot->tts_shouldFreeMin = false;
384  slot->tts_tuple = tuple;
385  slot->tts_mintuple = NULL;
386 
387  /* Mark extracted state invalid */
388  slot->tts_nvalid = 0;
389 
390  /*
391  * If tuple is on a disk page, keep the page pinned as long as we hold a
392  * pointer into it. We assume the caller already has such a pin.
393  *
394  * This is coded to optimize the case where the slot previously held a
395  * tuple on the same disk page: in that case releasing and re-acquiring
396  * the pin is a waste of cycles. This is a common situation during
397  * seqscans, so it's worth troubling over.
398  */
399  if (slot->tts_buffer != buffer)
400  {
401  if (BufferIsValid(slot->tts_buffer))
402  ReleaseBuffer(slot->tts_buffer);
403  slot->tts_buffer = buffer;
404  if (BufferIsValid(buffer))
405  IncrBufferRefCount(buffer);
406  }
407 
408  return slot;
409 }
410 
411 /* --------------------------------
412  * ExecStoreMinimalTuple
413  *
414  * Like ExecStoreTuple, but insert a "minimal" tuple into the slot.
415  *
416  * No 'buffer' parameter since minimal tuples are never stored in relations.
417  * --------------------------------
418  */
421  TupleTableSlot *slot,
422  bool shouldFree)
423 {
424  /*
425  * sanity checks
426  */
427  Assert(mtup != NULL);
428  Assert(slot != NULL);
429  Assert(slot->tts_tupleDescriptor != NULL);
430 
431  /*
432  * Free any old physical tuple belonging to the slot.
433  */
434  if (slot->tts_shouldFree)
435  heap_freetuple(slot->tts_tuple);
436  if (slot->tts_shouldFreeMin)
438 
439  /*
440  * Drop the pin on the referenced buffer, if there is one.
441  */
442  if (BufferIsValid(slot->tts_buffer))
443  ReleaseBuffer(slot->tts_buffer);
444 
445  slot->tts_buffer = InvalidBuffer;
446 
447  /*
448  * Store the new tuple into the specified slot.
449  */
450  slot->tts_isempty = false;
451  slot->tts_shouldFree = false;
452  slot->tts_shouldFreeMin = shouldFree;
453  slot->tts_tuple = &slot->tts_minhdr;
454  slot->tts_mintuple = mtup;
455 
456  slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
457  slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET);
458  /* no need to set t_self or t_tableOid since we won't allow access */
459 
460  /* Mark extracted state invalid */
461  slot->tts_nvalid = 0;
462 
463  return slot;
464 }
465 
466 /* --------------------------------
467  * ExecClearTuple
468  *
469  * This function is used to clear out a slot in the tuple table.
470  *
471  * NB: only the tuple is cleared, not the tuple descriptor (if any).
472  * --------------------------------
473  */
474 TupleTableSlot * /* return: slot passed */
475 ExecClearTuple(TupleTableSlot *slot) /* slot in which to store tuple */
476 {
477  /*
478  * sanity checks
479  */
480  Assert(slot != NULL);
481 
482  /*
483  * Free the old physical tuple if necessary.
484  */
485  if (slot->tts_shouldFree)
486  heap_freetuple(slot->tts_tuple);
487  if (slot->tts_shouldFreeMin)
489 
490  slot->tts_tuple = NULL;
491  slot->tts_mintuple = NULL;
492  slot->tts_shouldFree = false;
493  slot->tts_shouldFreeMin = false;
494 
495  /*
496  * Drop the pin on the referenced buffer, if there is one.
497  */
498  if (BufferIsValid(slot->tts_buffer))
499  ReleaseBuffer(slot->tts_buffer);
500 
501  slot->tts_buffer = InvalidBuffer;
502 
503  /*
504  * Mark it empty.
505  */
506  slot->tts_isempty = true;
507  slot->tts_nvalid = 0;
508 
509  return slot;
510 }
511 
512 /* --------------------------------
513  * ExecStoreVirtualTuple
514  * Mark a slot as containing a virtual tuple.
515  *
516  * The protocol for loading a slot with virtual tuple data is:
517  * * Call ExecClearTuple to mark the slot empty.
518  * * Store data into the Datum/isnull arrays.
519  * * Call ExecStoreVirtualTuple to mark the slot valid.
520  * This is a bit unclean but it avoids one round of data copying.
521  * --------------------------------
522  */
525 {
526  /*
527  * sanity checks
528  */
529  Assert(slot != NULL);
530  Assert(slot->tts_tupleDescriptor != NULL);
531  Assert(slot->tts_isempty);
532 
533  slot->tts_isempty = false;
534  slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
535 
536  return slot;
537 }
538 
539 /* --------------------------------
540  * ExecStoreAllNullTuple
541  * Set up the slot to contain a null in every column.
542  *
543  * At first glance this might sound just like ExecClearTuple, but it's
544  * entirely different: the slot ends up full, not empty.
545  * --------------------------------
546  */
549 {
550  /*
551  * sanity checks
552  */
553  Assert(slot != NULL);
554  Assert(slot->tts_tupleDescriptor != NULL);
555 
556  /* Clear any old contents */
557  ExecClearTuple(slot);
558 
559  /*
560  * Fill all the columns of the virtual tuple with nulls
561  */
562  MemSet(slot->tts_values, 0,
563  slot->tts_tupleDescriptor->natts * sizeof(Datum));
564  memset(slot->tts_isnull, true,
565  slot->tts_tupleDescriptor->natts * sizeof(bool));
566 
567  return ExecStoreVirtualTuple(slot);
568 }
569 
570 /* --------------------------------
571  * ExecCopySlotTuple
572  * Obtain a copy of a slot's regular physical tuple. The copy is
573  * palloc'd in the current memory context.
574  * The slot itself is undisturbed.
575  *
576  * This works even if the slot contains a virtual or minimal tuple;
577  * however the "system columns" of the result will not be meaningful.
578  * --------------------------------
579  */
580 HeapTuple
582 {
583  /*
584  * sanity checks
585  */
586  Assert(slot != NULL);
587  Assert(!slot->tts_isempty);
588 
589  /*
590  * If we have a physical tuple (either format) then just copy it.
591  */
592  if (TTS_HAS_PHYSICAL_TUPLE(slot))
593  return heap_copytuple(slot->tts_tuple);
594  if (slot->tts_mintuple)
596 
597  /*
598  * Otherwise we need to build a tuple from the Datum array.
599  */
601  slot->tts_values,
602  slot->tts_isnull);
603 }
604 
605 /* --------------------------------
606  * ExecCopySlotMinimalTuple
607  * Obtain a copy of a slot's minimal physical tuple. The copy is
608  * palloc'd in the current memory context.
609  * The slot itself is undisturbed.
610  * --------------------------------
611  */
614 {
615  /*
616  * sanity checks
617  */
618  Assert(slot != NULL);
619  Assert(!slot->tts_isempty);
620 
621  /*
622  * If we have a physical tuple then just copy it. Prefer to copy
623  * tts_mintuple since that's a tad cheaper.
624  */
625  if (slot->tts_mintuple)
627  if (slot->tts_tuple)
628  {
630  < slot->tts_tupleDescriptor->natts)
631  return minimal_expand_tuple(slot->tts_tuple,
632  slot->tts_tupleDescriptor);
633  else
635  }
636 
637  /*
638  * Otherwise we need to build a tuple from the Datum array.
639  */
641  slot->tts_values,
642  slot->tts_isnull);
643 }
644 
645 /* --------------------------------
646  * ExecFetchSlotTuple
647  * Fetch the slot's regular physical tuple.
648  *
649  * If the slot contains a virtual tuple, we convert it to physical
650  * form. The slot retains ownership of the physical tuple.
651  * If it contains a minimal tuple we convert to regular form and store
652  * that in addition to the minimal tuple (not instead of, because
653  * callers may hold pointers to Datums within the minimal tuple).
654  *
655  * The main difference between this and ExecMaterializeSlot() is that this
656  * does not guarantee that the contained tuple is local storage.
657  * Hence, the result must be treated as read-only.
658  * --------------------------------
659  */
660 HeapTuple
662 {
663  /*
664  * sanity checks
665  */
666  Assert(slot != NULL);
667  Assert(!slot->tts_isempty);
668 
669  /*
670  * If we have a regular physical tuple then just return it.
671  */
672  if (TTS_HAS_PHYSICAL_TUPLE(slot))
673  {
675  slot->tts_tupleDescriptor->natts)
676  {
677  HeapTuple tuple;
678  MemoryContext oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
679 
680  tuple = heap_expand_tuple(slot->tts_tuple,
681  slot->tts_tupleDescriptor);
682  MemoryContextSwitchTo(oldContext);
683  slot = ExecStoreTuple(tuple, slot, InvalidBuffer, true);
684  }
685  return slot->tts_tuple;
686  }
687 
688  /*
689  * Otherwise materialize the slot...
690  */
691  return ExecMaterializeSlot(slot);
692 }
693 
694 /* --------------------------------
695  * ExecFetchSlotMinimalTuple
696  * Fetch the slot's minimal physical tuple.
697  *
698  * If the slot contains a virtual tuple, we convert it to minimal
699  * physical form. The slot retains ownership of the minimal tuple.
700  * If it contains a regular tuple we convert to minimal form and store
701  * that in addition to the regular tuple (not instead of, because
702  * callers may hold pointers to Datums within the regular tuple).
703  *
704  * As above, the result must be treated as read-only.
705  * --------------------------------
706  */
709 {
710  MemoryContext oldContext;
711 
712  /*
713  * sanity checks
714  */
715  Assert(slot != NULL);
716  Assert(!slot->tts_isempty);
717 
718  /*
719  * If we have a minimal physical tuple (local or not) then just return it.
720  */
721  if (slot->tts_mintuple)
722  return slot->tts_mintuple;
723 
724  /*
725  * Otherwise, copy or build a minimal tuple, and store it into the slot.
726  *
727  * We may be called in a context that is shorter-lived than the tuple
728  * slot, but we have to ensure that the materialized tuple will survive
729  * anyway.
730  */
731  oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
733  slot->tts_shouldFreeMin = true;
734  MemoryContextSwitchTo(oldContext);
735 
736  /*
737  * Note: we may now have a situation where we have a local minimal tuple
738  * attached to a virtual or non-local physical tuple. There seems no harm
739  * in that at the moment, but if any materializes, we should change this
740  * function to force the slot into minimal-tuple-only state.
741  */
742 
743  return slot->tts_mintuple;
744 }
745 
746 /* --------------------------------
747  * ExecFetchSlotTupleDatum
748  * Fetch the slot's tuple as a composite-type Datum.
749  *
750  * The result is always freshly palloc'd in the caller's memory context.
751  * --------------------------------
752  */
753 Datum
755 {
756  HeapTuple tup;
757  TupleDesc tupdesc;
758 
759  /* Fetch slot's contents in regular-physical-tuple form */
760  tup = ExecFetchSlotTuple(slot);
761  tupdesc = slot->tts_tupleDescriptor;
762 
763  /* Convert to Datum form */
764  return heap_copy_tuple_as_datum(tup, tupdesc);
765 }
766 
767 /* --------------------------------
768  * ExecMaterializeSlot
769  * Force a slot into the "materialized" state.
770  *
771  * This causes the slot's tuple to be a local copy not dependent on
772  * any external storage. A pointer to the contained tuple is returned.
773  *
774  * A typical use for this operation is to prepare a computed tuple
775  * for being stored on disk. The original data may or may not be
776  * virtual, but in any case we need a private copy for heap_insert
777  * to scribble on.
778  * --------------------------------
779  */
780 HeapTuple
782 {
783  MemoryContext oldContext;
784 
785  /*
786  * sanity checks
787  */
788  Assert(slot != NULL);
789  Assert(!slot->tts_isempty);
790 
791  /*
792  * If we have a regular physical tuple, and it's locally palloc'd, we have
793  * nothing to do.
794  */
795  if (slot->tts_tuple && slot->tts_shouldFree)
796  return slot->tts_tuple;
797 
798  /*
799  * Otherwise, copy or build a physical tuple, and store it into the slot.
800  *
801  * We may be called in a context that is shorter-lived than the tuple
802  * slot, but we have to ensure that the materialized tuple will survive
803  * anyway.
804  */
805  oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
806  slot->tts_tuple = ExecCopySlotTuple(slot);
807  slot->tts_shouldFree = true;
808  MemoryContextSwitchTo(oldContext);
809 
810  /*
811  * Drop the pin on the referenced buffer, if there is one.
812  */
813  if (BufferIsValid(slot->tts_buffer))
814  ReleaseBuffer(slot->tts_buffer);
815 
816  slot->tts_buffer = InvalidBuffer;
817 
818  /*
819  * Mark extracted state invalid. This is important because the slot is
820  * not supposed to depend any more on the previous external data; we
821  * mustn't leave any dangling pass-by-reference datums in tts_values.
822  * However, we have not actually invalidated any such datums, if there
823  * happen to be any previously fetched from the slot. (Note in particular
824  * that we have not pfree'd tts_mintuple, if there is one.)
825  */
826  slot->tts_nvalid = 0;
827 
828  /*
829  * On the same principle of not depending on previous remote storage,
830  * forget the mintuple if it's not local storage. (If it is local
831  * storage, we must not pfree it now, since callers might have already
832  * fetched datum pointers referencing it.)
833  */
834  if (!slot->tts_shouldFreeMin)
835  slot->tts_mintuple = NULL;
836 
837  return slot->tts_tuple;
838 }
839 
840 /* --------------------------------
841  * ExecCopySlot
842  * Copy the source slot's contents into the destination slot.
843  *
844  * The destination acquires a private copy that will not go away
845  * if the source is cleared.
846  *
847  * The caller must ensure the slots have compatible tupdescs.
848  * --------------------------------
849  */
852 {
853  HeapTuple newTuple;
854  MemoryContext oldContext;
855 
856  /*
857  * There might be ways to optimize this when the source is virtual, but
858  * for now just always build a physical copy. Make sure it is in the
859  * right context.
860  */
861  oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt);
862  newTuple = ExecCopySlotTuple(srcslot);
863  MemoryContextSwitchTo(oldContext);
864 
865  return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
866 }
867 
868 
869 /* ----------------------------------------------------------------
870  * convenience initialization routines
871  * ----------------------------------------------------------------
872  */
873 
874 /* --------------------------------
875  * ExecInit{Result,Scan,Extra}TupleSlot[TL]
876  *
877  * These are convenience routines to initialize the specified slot
878  * in nodes inheriting the appropriate state. ExecInitExtraTupleSlot
879  * is used for initializing special-purpose slots.
880  * --------------------------------
881  */
882 
883 /* ----------------
884  * ExecInitResultTupleSlotTL
885  *
886  * Initialize result tuple slot, using the plan node's targetlist.
887  * ----------------
888  */
889 void
891 {
892  bool hasoid;
893  TupleDesc tupDesc;
894 
895  if (ExecContextForcesOids(planstate, &hasoid))
896  {
897  /* context forces OID choice; hasoid is now set correctly */
898  }
899  else
900  {
901  /* given free choice, don't leave space for OIDs in result tuples */
902  hasoid = false;
903  }
904 
905  tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
906 
907  planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable, tupDesc);
908 }
909 
910 /* ----------------
911  * ExecInitScanTupleSlot
912  * ----------------
913  */
914 void
915 ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
916 {
917  scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable,
918  tupledesc);
919  scanstate->ps.scandesc = tupledesc;
920 }
921 
922 /* ----------------
923  * ExecInitExtraTupleSlot
924  *
925  * Return a newly created slot. If tupledesc is non-NULL the slot will have
926  * that as its fixed tupledesc. Otherwise the caller needs to use
927  * ExecSetSlotDescriptor() to set the descriptor before use.
928  * ----------------
929  */
932 {
933  return ExecAllocTableSlot(&estate->es_tupleTable, tupledesc);
934 }
935 
936 /* ----------------
937  * ExecInitNullTupleSlot
938  *
939  * Build a slot containing an all-nulls tuple of the given type.
940  * This is used as a substitute for an input tuple when performing an
941  * outer join.
942  * ----------------
943  */
946 {
947  TupleTableSlot *slot = ExecInitExtraTupleSlot(estate, tupType);
948 
949  return ExecStoreAllNullTuple(slot);
950 }
951 
952 /* ----------------------------------------------------------------
953  * ExecTypeFromTL
954  *
955  * Generate a tuple descriptor for the result tuple of a targetlist.
956  * (A parse/plan tlist must be passed, not an ExprState tlist.)
957  * Note that resjunk columns, if any, are included in the result.
958  *
959  * Currently there are about 4 different places where we create
960  * TupleDescriptors. They should all be merged, or perhaps
961  * be rewritten to call BuildDesc().
962  * ----------------------------------------------------------------
963  */
964 TupleDesc
965 ExecTypeFromTL(List *targetList, bool hasoid)
966 {
967  return ExecTypeFromTLInternal(targetList, hasoid, false);
968 }
969 
970 /* ----------------------------------------------------------------
971  * ExecCleanTypeFromTL
972  *
973  * Same as above, but resjunk columns are omitted from the result.
974  * ----------------------------------------------------------------
975  */
976 TupleDesc
977 ExecCleanTypeFromTL(List *targetList, bool hasoid)
978 {
979  return ExecTypeFromTLInternal(targetList, hasoid, true);
980 }
981 
982 static TupleDesc
983 ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
984 {
985  TupleDesc typeInfo;
986  ListCell *l;
987  int len;
988  int cur_resno = 1;
989 
990  if (skipjunk)
991  len = ExecCleanTargetListLength(targetList);
992  else
993  len = ExecTargetListLength(targetList);
994  typeInfo = CreateTemplateTupleDesc(len, hasoid);
995 
996  foreach(l, targetList)
997  {
998  TargetEntry *tle = lfirst(l);
999 
1000  if (skipjunk && tle->resjunk)
1001  continue;
1002  TupleDescInitEntry(typeInfo,
1003  cur_resno,
1004  tle->resname,
1005  exprType((Node *) tle->expr),
1006  exprTypmod((Node *) tle->expr),
1007  0);
1008  TupleDescInitEntryCollation(typeInfo,
1009  cur_resno,
1010  exprCollation((Node *) tle->expr));
1011  cur_resno++;
1012  }
1013 
1014  return typeInfo;
1015 }
1016 
1017 /*
1018  * ExecTypeFromExprList - build a tuple descriptor from a list of Exprs
1019  *
1020  * This is roughly like ExecTypeFromTL, but we work from bare expressions
1021  * not TargetEntrys. No names are attached to the tupledesc's columns.
1022  */
1023 TupleDesc
1025 {
1026  TupleDesc typeInfo;
1027  ListCell *lc;
1028  int cur_resno = 1;
1029 
1030  typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
1031 
1032  foreach(lc, exprList)
1033  {
1034  Node *e = lfirst(lc);
1035 
1036  TupleDescInitEntry(typeInfo,
1037  cur_resno,
1038  NULL,
1039  exprType(e),
1040  exprTypmod(e),
1041  0);
1042  TupleDescInitEntryCollation(typeInfo,
1043  cur_resno,
1044  exprCollation(e));
1045  cur_resno++;
1046  }
1047 
1048  return typeInfo;
1049 }
1050 
1051 /*
1052  * ExecTypeSetColNames - set column names in a TupleDesc
1053  *
1054  * Column names must be provided as an alias list (list of String nodes).
1055  *
1056  * For some callers, the supplied tupdesc has a named rowtype (not RECORD)
1057  * and it is moderately likely that the alias list matches the column names
1058  * already present in the tupdesc. If we do change any column names then
1059  * we must reset the tupdesc's type to anonymous RECORD; but we avoid doing
1060  * so if no names change.
1061  */
1062 void
1063 ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
1064 {
1065  bool modified = false;
1066  int colno = 0;
1067  ListCell *lc;
1068 
1069  foreach(lc, namesList)
1070  {
1071  char *cname = strVal(lfirst(lc));
1072  Form_pg_attribute attr;
1073 
1074  /* Guard against too-long names list */
1075  if (colno >= typeInfo->natts)
1076  break;
1077  attr = TupleDescAttr(typeInfo, colno);
1078  colno++;
1079 
1080  /* Ignore empty aliases (these must be for dropped columns) */
1081  if (cname[0] == '\0')
1082  continue;
1083 
1084  /* Change tupdesc only if alias is actually different */
1085  if (strcmp(cname, NameStr(attr->attname)) != 0)
1086  {
1087  namestrcpy(&(attr->attname), cname);
1088  modified = true;
1089  }
1090  }
1091 
1092  /* If we modified the tupdesc, it's now a new record type */
1093  if (modified)
1094  {
1095  typeInfo->tdtypeid = RECORDOID;
1096  typeInfo->tdtypmod = -1;
1097  }
1098 }
1099 
1100 /*
1101  * BlessTupleDesc - make a completed tuple descriptor useful for SRFs
1102  *
1103  * Rowtype Datums returned by a function must contain valid type information.
1104  * This happens "for free" if the tupdesc came from a relcache entry, but
1105  * not if we have manufactured a tupdesc for a transient RECORD datatype.
1106  * In that case we have to notify typcache.c of the existence of the type.
1107  */
1108 TupleDesc
1110 {
1111  if (tupdesc->tdtypeid == RECORDOID &&
1112  tupdesc->tdtypmod < 0)
1113  assign_record_type_typmod(tupdesc);
1114 
1115  return tupdesc; /* just for notational convenience */
1116 }
1117 
1118 /*
1119  * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc
1120  *
1121  * Note: this is obsolete; it is sufficient to call BlessTupleDesc on
1122  * the tupdesc. We keep it around just for backwards compatibility with
1123  * existing user-written SRFs.
1124  */
1127 {
1128  TupleTableSlot *slot;
1129 
1130  /* The useful work is here */
1131  BlessTupleDesc(tupdesc);
1132 
1133  /* Make a standalone slot */
1134  slot = MakeSingleTupleTableSlot(tupdesc);
1135 
1136  /* Return the slot */
1137  return slot;
1138 }
1139 
1140 /*
1141  * TupleDescGetAttInMetadata - Build an AttInMetadata structure based on the
1142  * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
1143  * to produce a properly formed tuple.
1144  */
1145 AttInMetadata *
1147 {
1148  int natts = tupdesc->natts;
1149  int i;
1150  Oid atttypeid;
1151  Oid attinfuncid;
1152  FmgrInfo *attinfuncinfo;
1153  Oid *attioparams;
1154  int32 *atttypmods;
1155  AttInMetadata *attinmeta;
1156 
1157  attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
1158 
1159  /* "Bless" the tupledesc so that we can make rowtype datums with it */
1160  attinmeta->tupdesc = BlessTupleDesc(tupdesc);
1161 
1162  /*
1163  * Gather info needed later to call the "in" function for each attribute
1164  */
1165  attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
1166  attioparams = (Oid *) palloc0(natts * sizeof(Oid));
1167  atttypmods = (int32 *) palloc0(natts * sizeof(int32));
1168 
1169  for (i = 0; i < natts; i++)
1170  {
1171  Form_pg_attribute att = TupleDescAttr(tupdesc, i);
1172 
1173  /* Ignore dropped attributes */
1174  if (!att->attisdropped)
1175  {
1176  atttypeid = att->atttypid;
1177  getTypeInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
1178  fmgr_info(attinfuncid, &attinfuncinfo[i]);
1179  atttypmods[i] = att->atttypmod;
1180  }
1181  }
1182  attinmeta->attinfuncs = attinfuncinfo;
1183  attinmeta->attioparams = attioparams;
1184  attinmeta->atttypmods = atttypmods;
1185 
1186  return attinmeta;
1187 }
1188 
1189 /*
1190  * BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
1191  * values is an array of C strings, one for each attribute of the return tuple.
1192  * A NULL string pointer indicates we want to create a NULL field.
1193  */
1194 HeapTuple
1196 {
1197  TupleDesc tupdesc = attinmeta->tupdesc;
1198  int natts = tupdesc->natts;
1199  Datum *dvalues;
1200  bool *nulls;
1201  int i;
1202  HeapTuple tuple;
1203 
1204  dvalues = (Datum *) palloc(natts * sizeof(Datum));
1205  nulls = (bool *) palloc(natts * sizeof(bool));
1206 
1207  /*
1208  * Call the "in" function for each non-dropped attribute, even for nulls,
1209  * to support domains.
1210  */
1211  for (i = 0; i < natts; i++)
1212  {
1213  if (!TupleDescAttr(tupdesc, i)->attisdropped)
1214  {
1215  /* Non-dropped attributes */
1216  dvalues[i] = InputFunctionCall(&attinmeta->attinfuncs[i],
1217  values[i],
1218  attinmeta->attioparams[i],
1219  attinmeta->atttypmods[i]);
1220  if (values[i] != NULL)
1221  nulls[i] = false;
1222  else
1223  nulls[i] = true;
1224  }
1225  else
1226  {
1227  /* Handle dropped attributes by setting to NULL */
1228  dvalues[i] = (Datum) 0;
1229  nulls[i] = true;
1230  }
1231  }
1232 
1233  /*
1234  * Form a tuple
1235  */
1236  tuple = heap_form_tuple(tupdesc, dvalues, nulls);
1237 
1238  /*
1239  * Release locally palloc'd space. XXX would probably be good to pfree
1240  * values of pass-by-reference datums, as well.
1241  */
1242  pfree(dvalues);
1243  pfree(nulls);
1244 
1245  return tuple;
1246 }
1247 
1248 /*
1249  * HeapTupleHeaderGetDatum - convert a HeapTupleHeader pointer to a Datum.
1250  *
1251  * This must *not* get applied to an on-disk tuple; the tuple should be
1252  * freshly made by heap_form_tuple or some wrapper routine for it (such as
1253  * BuildTupleFromCStrings). Be sure also that the tupledesc used to build
1254  * the tuple has a properly "blessed" rowtype.
1255  *
1256  * Formerly this was a macro equivalent to PointerGetDatum, relying on the
1257  * fact that heap_form_tuple fills in the appropriate tuple header fields
1258  * for a composite Datum. However, we now require that composite Datums not
1259  * contain any external TOAST pointers. We do not want heap_form_tuple itself
1260  * to enforce that; more specifically, the rule applies only to actual Datums
1261  * and not to HeapTuple structures. Therefore, HeapTupleHeaderGetDatum is
1262  * now a function that detects whether there are externally-toasted fields
1263  * and constructs a new tuple with inlined fields if so. We still need
1264  * heap_form_tuple to insert the Datum header fields, because otherwise this
1265  * code would have no way to obtain a tupledesc for the tuple.
1266  *
1267  * Note that if we do build a new tuple, it's palloc'd in the current
1268  * memory context. Beware of code that changes context between the initial
1269  * heap_form_tuple/etc call and calling HeapTuple(Header)GetDatum.
1270  *
1271  * For performance-critical callers, it could be worthwhile to take extra
1272  * steps to ensure that there aren't TOAST pointers in the output of
1273  * heap_form_tuple to begin with. It's likely however that the costs of the
1274  * typcache lookup and tuple disassembly/reassembly are swamped by TOAST
1275  * dereference costs, so that the benefits of such extra effort would be
1276  * minimal.
1277  *
1278  * XXX it would likely be better to create wrapper functions that produce
1279  * a composite Datum from the field values in one step. However, there's
1280  * enough code using the existing APIs that we couldn't get rid of this
1281  * hack anytime soon.
1282  */
1283 Datum
1285 {
1286  Datum result;
1287  TupleDesc tupDesc;
1288 
1289  /* No work if there are no external TOAST pointers in the tuple */
1290  if (!HeapTupleHeaderHasExternal(tuple))
1291  return PointerGetDatum(tuple);
1292 
1293  /* Use the type data saved by heap_form_tuple to look up the rowtype */
1295  HeapTupleHeaderGetTypMod(tuple));
1296 
1297  /* And do the flattening */
1298  result = toast_flatten_tuple_to_datum(tuple,
1300  tupDesc);
1301 
1302  ReleaseTupleDesc(tupDesc);
1303 
1304  return result;
1305 }
1306 
1307 
1308 /*
1309  * Functions for sending tuples to the frontend (or other specified destination)
1310  * as though it is a SELECT result. These are used by utility commands that
1311  * need to project directly to the destination and don't need or want full
1312  * table function capability. Currently used by EXPLAIN and SHOW ALL.
1313  */
1316 {
1317  TupOutputState *tstate;
1318 
1319  tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
1320 
1321  tstate->slot = MakeSingleTupleTableSlot(tupdesc);
1322  tstate->dest = dest;
1323 
1324  tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc);
1325 
1326  return tstate;
1327 }
1328 
1329 /*
1330  * write a single tuple
1331  */
1332 void
1333 do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
1334 {
1335  TupleTableSlot *slot = tstate->slot;
1336  int natts = slot->tts_tupleDescriptor->natts;
1337 
1338  /* make sure the slot is clear */
1339  ExecClearTuple(slot);
1340 
1341  /* insert data */
1342  memcpy(slot->tts_values, values, natts * sizeof(Datum));
1343  memcpy(slot->tts_isnull, isnull, natts * sizeof(bool));
1344 
1345  /* mark slot as containing a virtual tuple */
1346  ExecStoreVirtualTuple(slot);
1347 
1348  /* send the tuple to the receiver */
1349  (void) tstate->dest->receiveSlot(slot, tstate->dest);
1350 
1351  /* clean up */
1352  ExecClearTuple(slot);
1353 }
1354 
1355 /*
1356  * write a chunk of text, breaking at newline characters
1357  *
1358  * Should only be used with a single-TEXT-attribute tupdesc.
1359  */
1360 void
1361 do_text_output_multiline(TupOutputState *tstate, const char *txt)
1362 {
1363  Datum values[1];
1364  bool isnull[1] = {false};
1365 
1366  while (*txt)
1367  {
1368  const char *eol;
1369  int len;
1370 
1371  eol = strchr(txt, '\n');
1372  if (eol)
1373  {
1374  len = eol - txt;
1375  eol++;
1376  }
1377  else
1378  {
1379  len = strlen(txt);
1380  eol = txt + len;
1381  }
1382 
1383  values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
1384  do_tup_output(tstate, values, isnull);
1385  pfree(DatumGetPointer(values[0]));
1386  txt = eol;
1387  }
1388 }
1389 
1390 void
1392 {
1393  tstate->dest->rShutdown(tstate->dest);
1394  /* note that destroying the dest is not ours to do */
1396  pfree(tstate);
1397 }
bool(* receiveSlot)(TupleTableSlot *slot, DestReceiver *self)
Definition: dest.h:118
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:722
TupleTableSlot * ExecStoreTuple(HeapTuple tuple, TupleTableSlot *slot, Buffer buffer, bool shouldFree)
Definition: execTuples.c:356
Definition: fmgr.h:56
int ExecTargetListLength(List *targetlist)
Definition: execUtils.c:1039
bool tts_isempty
Definition: tuptable.h:116
#define IsA(nodeptr, _type_)
Definition: nodes.h:567
Oid tdtypeid
Definition: tupdesc.h:83
TupleTableSlot * ExecStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, bool shouldFree)
Definition: execTuples.c:420
TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod)
Definition: typcache.c:1641
TupleTableSlot * ExecStoreAllNullTuple(TupleTableSlot *slot)
Definition: execTuples.c:548
static TupleDesc ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
Definition: execTuples.c:983
MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot)
Definition: execTuples.c:708
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
#define PointerGetDatum(X)
Definition: postgres.h:541
HeapTupleHeaderData * HeapTupleHeader
Definition: htup.h:23
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:93
MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot)
Definition: execTuples.c:613
void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
Definition: execTuples.c:1333
TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: execTuples.c:475
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define InvalidBuffer
Definition: buf.h:25
Definition: nodes.h:516
#define strVal(v)
Definition: value.h:54
#define MemSet(start, val, len)
Definition: c.h:908
bool tts_shouldFreeMin
Definition: tuptable.h:118
MemoryContext tts_mcxt
Definition: tuptable.h:125
Datum * tts_values
Definition: tuptable.h:130
int32 * atttypmods
Definition: funcapi.h:48
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1195
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3309
TupleTableSlot * slot
Definition: executor.h:446
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1074
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
unsigned int Oid
Definition: postgres_ext.h:31
char * resname
Definition: primnodes.h:1377
int namestrcpy(Name name, const char *str)
Definition: name.c:216
MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1880
Oid * attioparams
Definition: funcapi.h:45
int natts
Definition: tupdesc.h:82
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc)
Definition: execTuples.c:931
int32 tdtypmod
Definition: tupdesc.h:84
signed int int32
Definition: c.h:313
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:1195
void assign_record_type_typmod(TupleDesc tupDesc)
Definition: typcache.c:1761
HeapTupleHeader t_data
Definition: htup.h:68
#define HeapTupleHeaderGetTypMod(tup)
Definition: htup_details.h:467
NodeTag type
Definition: tuptable.h:115
PlanState ps
Definition: execnodes.h:1192
TupleTableSlot * ps_ResultTupleSlot
Definition: execnodes.h:946
TupleTableSlot * ExecAllocTableSlot(List **tupleTable, TupleDesc desc)
Definition: execTuples.c:167
void pfree(void *pointer)
Definition: mcxt.c:1031
TupleTableSlot * ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
Definition: execTuples.c:945
bool resjunk
Definition: primnodes.h:1382
void end_tup_output(TupOutputState *tstate)
Definition: execTuples.c:1391
HeapTupleData tts_minhdr
Definition: tuptable.h:134
void heap_free_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1868
#define HeapTupleHeaderGetNatts(tup)
Definition: htup_details.h:544
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:124
void(* rStartup)(DestReceiver *self, int operation, TupleDesc typeinfo)
Definition: dest.h:121
void TupleDescInitEntryCollation(TupleDesc desc, AttrNumber attributeNumber, Oid collationid)
Definition: tupdesc.c:761
#define lfirst_node(type, lc)
Definition: pg_list.h:109
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1109
uint32 t_len
Definition: htup.h:64
Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, uint32 tup_len, TupleDesc tupleDesc)
Definition: tuptoaster.c:1187
MinimalTuple minimal_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1011
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:161
bool * tts_isnull
Definition: tuptable.h:132
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:247
HeapTuple heap_expand_tuple(HeapTuple sourceTuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1023
TupleDesc tupdesc
Definition: funcapi.h:39
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
MemoryContext CurrentMemoryContext
Definition: mcxt.c:38
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc)
Definition: execTuples.c:232
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:600
bool tts_shouldFree
Definition: tuptable.h:117
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2617
Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc)
Definition: heaptuple.c:1038
TupleDesc ExecTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:965
List * lappend(List *list, void *datum)
Definition: list.c:128
int ExecCleanTargetListLength(List *targetlist)
Definition: execUtils.c:1049
TupOutputState * begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
Definition: execTuples.c:1315
MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1791
HeapTuple ExecCopySlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:581
bool tts_fixedTupleDescriptor
Definition: tuptable.h:137
HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup)
Definition: heaptuple.c:1899
TupleDesc tts_tupleDescriptor
Definition: tuptable.h:124
TupleTableSlot * TupleDescGetSlot(TupleDesc tupdesc)
Definition: execTuples.c:1126
List * es_tupleTable
Definition: execnodes.h:525
void do_text_output_multiline(TupOutputState *tstate, const char *txt)
Definition: execTuples.c:1361
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
Definition: execTuples.c:186
void * palloc0(Size size)
Definition: mcxt.c:955
uintptr_t Datum
Definition: postgres.h:367
void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc)
Definition: execTuples.c:281
TupleDesc scandesc
Definition: execnodes.h:955
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:1146
#define HeapTupleHeaderGetTypeId(tup)
Definition: htup_details.h:457
#define HeapTupleHeaderHasExternal(tup)
Definition: htup_details.h:552
void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
Definition: execTuples.c:890
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1709
Plan * plan
Definition: execnodes.h:912
struct TupleTableSlot TupleTableSlot
TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
Definition: execTuples.c:851
#define Assert(condition)
Definition: c.h:699
#define lfirst(lc)
Definition: pg_list.h:106
Expr * expr
Definition: primnodes.h:1375
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
size_t Size
Definition: c.h:433
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
static int list_length(const List *l)
Definition: pg_list.h:89
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
#define MAXALIGN(LEN)
Definition: c.h:652
#define BufferIsValid(bufnum)
Definition: bufmgr.h:114
HeapTuple ExecMaterializeSlot(TupleTableSlot *slot)
Definition: execTuples.c:781
TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid)
Definition: tupdesc.c:45
MinimalTuple tts_mintuple
Definition: tuptable.h:133
#define MINIMAL_TUPLE_OFFSET
Definition: htup_details.h:632
TupleTableSlot * MakeTupleTableSlot(TupleDesc tupleDesc)
Definition: execTuples.c:113
void(* rShutdown)(DestReceiver *self)
Definition: dest.h:124
List * targetlist
Definition: plannodes.h:147
HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot)
Definition: execTuples.c:661
#define DatumGetPointer(X)
Definition: postgres.h:534
#define PinTupleDesc(tupdesc)
Definition: tupdesc.h:118
static Datum values[MAXATTR]
Definition: bootstrap.c:164
e
Definition: preproc-init.c:82
MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup)
Definition: heaptuple.c:1921
Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple)
Definition: execTuples.c:1284
TupleDesc ExecTypeFromExprList(List *exprList)
Definition: execTuples.c:1024
void * palloc(Size size)
Definition: mcxt.c:924
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
void list_free(List *list)
Definition: list.c:1133
int i
#define NameStr(name)
Definition: c.h:576
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
Definition: execTuples.c:915
TupleDesc ExecCleanTypeFromTL(List *targetList, bool hasoid)
Definition: execTuples.c:977
bool ExecContextForcesOids(PlanState *planstate, bool *hasoids)
Definition: execMain.c:1521
FmgrInfo * attinfuncs
Definition: funcapi.h:42
HeapTuple tts_tuple
Definition: tuptable.h:122
DestReceiver * dest
Definition: executor.h:447
Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot)
Definition: execTuples.c:754
Buffer tts_buffer
Definition: tuptable.h:126
#define ReleaseTupleDesc(tupdesc)
Definition: tupdesc.h:124
Definition: pg_list.h:45
int Buffer
Definition: buf.h:23
void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
Definition: execTuples.c:1063
void IncrBufferRefCount(Buffer buffer)
Definition: bufmgr.c:3347
#define TTS_HAS_PHYSICAL_TUPLE(slot)
Definition: tuptable.h:140
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:524
#define HeapTupleHeaderGetDatumLength(tup)
Definition: htup_details.h:451