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