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