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  */
112 TupleTableSlot *
MakeTupleTableSlot(TupleDesc tupleDesc)113 MakeTupleTableSlot(TupleDesc tupleDesc)
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;
137 	slot->tts_mcxt = CurrentMemoryContext;
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  */
166 TupleTableSlot *
ExecAllocTableSlot(List ** tupleTable,TupleDesc desc)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
ExecResetTupleTable(List * tupleTable,bool shouldFree)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 	{
193 		TupleTableSlot *slot = lfirst_node(TupleTableSlot, lc);
194 
195 		/* Always release resources and reset the slot to empty */
196 		ExecClearTuple(slot);
197 		if (slot->tts_tupleDescriptor)
198 		{
199 			ReleaseTupleDesc(slot->tts_tupleDescriptor);
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  */
231 TupleTableSlot *
MakeSingleTupleTableSlot(TupleDesc tupdesc)232 MakeSingleTupleTableSlot(TupleDesc tupdesc)
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
ExecDropSingleTupleTableSlot(TupleTableSlot * slot)247 ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
248 {
249 	/* This should match ExecResetTupleTable's processing of one slot */
250 	Assert(IsA(slot, TupleTableSlot));
251 	ExecClearTuple(slot);
252 	if (slot->tts_tupleDescriptor)
253 		ReleaseTupleDesc(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
ExecSetSlotDescriptor(TupleTableSlot * slot,TupleDesc tupdesc)281 ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
282 					  TupleDesc tupdesc)	/* new tuple descriptor */
283 {
284 	Assert(!slot->tts_fixedTupleDescriptor);
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)
294 		ReleaseTupleDesc(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  */
355 TupleTableSlot *
ExecStoreTuple(HeapTuple tuple,TupleTableSlot * slot,Buffer buffer,bool shouldFree)356 ExecStoreTuple(HeapTuple tuple,
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)
376 		heap_free_minimal_tuple(slot->tts_mintuple);
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  */
419 TupleTableSlot *
ExecStoreMinimalTuple(MinimalTuple mtup,TupleTableSlot * slot,bool shouldFree)420 ExecStoreMinimalTuple(MinimalTuple mtup,
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)
437 		heap_free_minimal_tuple(slot->tts_mintuple);
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 */
ExecClearTuple(TupleTableSlot * slot)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)
488 		heap_free_minimal_tuple(slot->tts_mintuple);
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  */
523 TupleTableSlot *
ExecStoreVirtualTuple(TupleTableSlot * slot)524 ExecStoreVirtualTuple(TupleTableSlot *slot)
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  */
547 TupleTableSlot *
ExecStoreAllNullTuple(TupleTableSlot * slot)548 ExecStoreAllNullTuple(TupleTableSlot *slot)
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
ExecCopySlotTuple(TupleTableSlot * slot)581 ExecCopySlotTuple(TupleTableSlot *slot)
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)
595 		return heap_tuple_from_minimal_tuple(slot->tts_mintuple);
596 
597 	/*
598 	 * Otherwise we need to build a tuple from the Datum array.
599 	 */
600 	return heap_form_tuple(slot->tts_tupleDescriptor,
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  */
612 MinimalTuple
ExecCopySlotMinimalTuple(TupleTableSlot * slot)613 ExecCopySlotMinimalTuple(TupleTableSlot *slot)
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)
626 		return heap_copy_minimal_tuple(slot->tts_mintuple);
627 	if (slot->tts_tuple)
628 	{
629 		if (HeapTupleHeaderGetNatts(slot->tts_tuple->t_data)
630 			< slot->tts_tupleDescriptor->natts)
631 			return minimal_expand_tuple(slot->tts_tuple,
632 										slot->tts_tupleDescriptor);
633 		else
634 			return minimal_tuple_from_heap_tuple(slot->tts_tuple);
635 	}
636 
637 	/*
638 	 * Otherwise we need to build a tuple from the Datum array.
639 	 */
640 	return heap_form_minimal_tuple(slot->tts_tupleDescriptor,
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
ExecFetchSlotTuple(TupleTableSlot * slot)661 ExecFetchSlotTuple(TupleTableSlot *slot)
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 	{
674 		if (HeapTupleHeaderGetNatts(slot->tts_tuple->t_data) <
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  */
707 MinimalTuple
ExecFetchSlotMinimalTuple(TupleTableSlot * slot)708 ExecFetchSlotMinimalTuple(TupleTableSlot *slot)
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);
732 	slot->tts_mintuple = ExecCopySlotMinimalTuple(slot);
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
ExecFetchSlotTupleDatum(TupleTableSlot * slot)754 ExecFetchSlotTupleDatum(TupleTableSlot *slot)
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
ExecMaterializeSlot(TupleTableSlot * slot)781 ExecMaterializeSlot(TupleTableSlot *slot)
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  */
850 TupleTableSlot *
ExecCopySlot(TupleTableSlot * dstslot,TupleTableSlot * srcslot)851 ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
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
ExecInitResultTupleSlotTL(EState * estate,PlanState * planstate)890 ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
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
ExecInitScanTupleSlot(EState * estate,ScanState * scanstate,TupleDesc tupledesc)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  */
930 TupleTableSlot *
ExecInitExtraTupleSlot(EState * estate,TupleDesc tupledesc)931 ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc)
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  */
944 TupleTableSlot *
ExecInitNullTupleSlot(EState * estate,TupleDesc tupType)945 ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
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
ExecTypeFromTL(List * targetList,bool hasoid)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
ExecCleanTypeFromTL(List * targetList,bool hasoid)977 ExecCleanTypeFromTL(List *targetList, bool hasoid)
978 {
979 	return ExecTypeFromTLInternal(targetList, hasoid, true);
980 }
981 
982 static TupleDesc
ExecTypeFromTLInternal(List * targetList,bool hasoid,bool skipjunk)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
ExecTypeFromExprList(List * exprList)1024 ExecTypeFromExprList(List *exprList)
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
ExecTypeSetColNames(TupleDesc typeInfo,List * namesList)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
BlessTupleDesc(TupleDesc tupdesc)1109 BlessTupleDesc(TupleDesc tupdesc)
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  */
1125 TupleTableSlot *
TupleDescGetSlot(TupleDesc tupdesc)1126 TupleDescGetSlot(TupleDesc tupdesc)
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 *
TupleDescGetAttInMetadata(TupleDesc tupdesc)1146 TupleDescGetAttInMetadata(TupleDesc tupdesc)
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
BuildTupleFromCStrings(AttInMetadata * attinmeta,char ** values)1195 BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
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
HeapTupleHeaderGetDatum(HeapTupleHeader tuple)1284 HeapTupleHeaderGetDatum(HeapTupleHeader tuple)
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 */
1294 	tupDesc = lookup_rowtype_tupdesc(HeapTupleHeaderGetTypeId(tuple),
1295 									 HeapTupleHeaderGetTypMod(tuple));
1296 
1297 	/* And do the flattening */
1298 	result = toast_flatten_tuple_to_datum(tuple,
1299 										  HeapTupleHeaderGetDatumLength(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  */
1314 TupOutputState *
begin_tup_output_tupdesc(DestReceiver * dest,TupleDesc tupdesc)1315 begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
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
do_tup_output(TupOutputState * tstate,Datum * values,bool * isnull)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
do_text_output_multiline(TupOutputState * tstate,const char * txt)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
end_tup_output(TupOutputState * tstate)1391 end_tup_output(TupOutputState *tstate)
1392 {
1393 	tstate->dest->rShutdown(tstate->dest);
1394 	/* note that destroying the dest is not ours to do */
1395 	ExecDropSingleTupleTableSlot(tstate->slot);
1396 	pfree(tstate);
1397 }
1398