Add support for user-defined I/O conversion casts.
[PostgreSQL.git] / src / backend / executor / execTuples.c
blob42d550b223a07aed47f6e75fd1262c01b1435c81
1 /*-------------------------------------------------------------------------
3 * execTuples.c
4 * Routines dealing with the executor tuple tables. These are used to
5 * ensure that the executor frees copies of tuples (made by
6 * ExecTargetList) properly.
8 * Routines dealing with the type information for tuples. Currently,
9 * the type information for a tuple is an array of FormData_pg_attribute.
10 * This information is needed by routines manipulating tuples
11 * (getattribute, formtuple, etc.).
13 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
14 * Portions Copyright (c) 1994, Regents of the University of California
17 * IDENTIFICATION
18 * $PostgreSQL$
20 *-------------------------------------------------------------------------
23 * INTERFACE ROUTINES
25 * TABLE CREATE/DELETE
26 * ExecCreateTupleTable - create a new tuple table
27 * ExecDropTupleTable - destroy a table
28 * MakeSingleTupleTableSlot - make a single-slot table
29 * ExecDropSingleTupleTableSlot - destroy same
31 * SLOT RESERVATION
32 * ExecAllocTableSlot - find an available slot in the table
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
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 /
51 * Routines that probably belong somewhere else:
52 * ExecTypeFromTL - form a TupleDesc from a target list
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.
58 * At ExecutorStart()
59 * ----------------
60 * - InitPlan() calls ExecCreateTupleTable() to create the tuple
61 * table which will hold tuples processed by the executor.
63 * - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
64 * ExecInitResultTupleSlot() to reserve places in the tuple
65 * table for the tuples returned by the access methods and the
66 * tuples resulting from performing target list projections.
68 * During ExecutorRun()
69 * ----------------
70 * - SeqNext() calls ExecStoreTuple() to place the tuple returned
71 * by the access methods into the scan tuple slot.
73 * - ExecSeqScan() calls ExecStoreTuple() to take the result
74 * tuple from ExecProject() and place it into the result tuple slot.
76 * - ExecutePlan() calls ExecSelect(), which passes the result slot
77 * to printtup(), which uses slot_getallattrs() to extract the
78 * individual Datums for printing.
80 * At ExecutorEnd()
81 * ----------------
82 * - EndPlan() calls ExecDropTupleTable() to clean up any remaining
83 * tuples left over from executing the query.
85 * The important thing to watch in the executor code is how pointers
86 * to the slots containing tuples are passed instead of the tuples
87 * themselves. This facilitates the communication of related information
88 * (such as whether or not a tuple should be pfreed, what buffer contains
89 * this tuple, the tuple's tuple descriptor, etc). It also allows us
90 * to avoid physically constructing projection tuples in many cases.
92 #include "postgres.h"
94 #include "funcapi.h"
95 #include "catalog/pg_type.h"
96 #include "nodes/nodeFuncs.h"
97 #include "storage/bufmgr.h"
98 #include "utils/lsyscache.h"
99 #include "utils/typcache.h"
102 static TupleDesc ExecTypeFromTLInternal(List *targetList,
103 bool hasoid, bool skipjunk);
106 /* ----------------------------------------------------------------
107 * tuple table create/delete functions
108 * ----------------------------------------------------------------
111 /* --------------------------------
112 * ExecCreateTupleTable
114 * This creates a new tuple table of the specified size.
116 * This should be used by InitPlan() to allocate the table.
117 * The table's address will be stored in the EState structure.
118 * --------------------------------
120 TupleTable
121 ExecCreateTupleTable(int tableSize)
123 TupleTable newtable;
124 int i;
127 * sanity checks
129 Assert(tableSize >= 1);
132 * allocate the table itself
134 newtable = (TupleTable) palloc(sizeof(TupleTableData) +
135 (tableSize - 1) *sizeof(TupleTableSlot));
136 newtable->size = tableSize;
137 newtable->next = 0;
140 * initialize all the slots to empty states
142 for (i = 0; i < tableSize; i++)
144 TupleTableSlot *slot = &(newtable->array[i]);
146 slot->type = T_TupleTableSlot;
147 slot->tts_isempty = true;
148 slot->tts_shouldFree = false;
149 slot->tts_tuple = NULL;
150 slot->tts_tupleDescriptor = NULL;
151 slot->tts_mcxt = CurrentMemoryContext;
152 slot->tts_buffer = InvalidBuffer;
153 slot->tts_nvalid = 0;
154 slot->tts_values = NULL;
155 slot->tts_isnull = NULL;
156 slot->tts_mintuple = NULL;
159 return newtable;
162 /* --------------------------------
163 * ExecDropTupleTable
165 * This frees the storage used by the tuple table itself
166 * and optionally frees the contents of the table also.
167 * It is expected that this routine be called by EndPlan().
168 * --------------------------------
170 void
171 ExecDropTupleTable(TupleTable table, /* tuple table */
172 bool shouldFree) /* true if we should free slot
173 * contents */
176 * sanity checks
178 Assert(table != NULL);
181 * first free all the valid pointers in the tuple array and drop refcounts
182 * of any referenced buffers, if that's what the caller wants. (There is
183 * probably no good reason for the caller ever not to want it!)
185 if (shouldFree)
187 int next = table->next;
188 int i;
190 for (i = 0; i < next; i++)
192 TupleTableSlot *slot = &(table->array[i]);
194 ExecClearTuple(slot);
195 if (slot->tts_tupleDescriptor)
196 ReleaseTupleDesc(slot->tts_tupleDescriptor);
197 if (slot->tts_values)
198 pfree(slot->tts_values);
199 if (slot->tts_isnull)
200 pfree(slot->tts_isnull);
205 * finally free the tuple table itself.
207 pfree(table);
210 /* --------------------------------
211 * MakeSingleTupleTableSlot
213 * This is a convenience routine for operations that need a
214 * standalone TupleTableSlot not gotten from the main executor
215 * tuple table. It makes a single slot and initializes it as
216 * though by ExecSetSlotDescriptor(slot, tupdesc).
217 * --------------------------------
219 TupleTableSlot *
220 MakeSingleTupleTableSlot(TupleDesc tupdesc)
222 TupleTableSlot *slot = makeNode(TupleTableSlot);
224 /* This should match ExecCreateTupleTable() */
225 slot->tts_isempty = true;
226 slot->tts_shouldFree = false;
227 slot->tts_tuple = NULL;
228 slot->tts_tupleDescriptor = NULL;
229 slot->tts_mcxt = CurrentMemoryContext;
230 slot->tts_buffer = InvalidBuffer;
231 slot->tts_nvalid = 0;
232 slot->tts_values = NULL;
233 slot->tts_isnull = NULL;
234 slot->tts_mintuple = NULL;
236 ExecSetSlotDescriptor(slot, tupdesc);
238 return slot;
241 /* --------------------------------
242 * ExecDropSingleTupleTableSlot
244 * Release a TupleTableSlot made with MakeSingleTupleTableSlot.
245 * --------------------------------
247 void
248 ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
251 * sanity checks
253 Assert(slot != NULL);
255 ExecClearTuple(slot);
256 if (slot->tts_tupleDescriptor)
257 ReleaseTupleDesc(slot->tts_tupleDescriptor);
258 if (slot->tts_values)
259 pfree(slot->tts_values);
260 if (slot->tts_isnull)
261 pfree(slot->tts_isnull);
263 pfree(slot);
267 /* ----------------------------------------------------------------
268 * tuple table slot reservation functions
269 * ----------------------------------------------------------------
272 /* --------------------------------
273 * ExecAllocTableSlot
275 * This routine is used to reserve slots in the table for
276 * use by the various plan nodes. It is expected to be
277 * called by the node init routines (ex: ExecInitNestLoop)
278 * once per slot needed by the node. Not all nodes need
279 * slots (some just pass tuples around).
280 * --------------------------------
282 TupleTableSlot *
283 ExecAllocTableSlot(TupleTable table)
285 int slotnum; /* new slot number */
288 * sanity checks
290 Assert(table != NULL);
293 * We expect that the table was made big enough to begin with. We cannot
294 * reallocate it on the fly since previous plan nodes have already got
295 * pointers to individual entries.
297 if (table->next >= table->size)
298 elog(ERROR, "plan requires more slots than are available");
300 slotnum = table->next;
301 table->next++;
303 return &(table->array[slotnum]);
306 /* ----------------------------------------------------------------
307 * tuple table slot accessor functions
308 * ----------------------------------------------------------------
311 /* --------------------------------
312 * ExecSetSlotDescriptor
314 * This function is used to set the tuple descriptor associated
315 * with the slot's tuple. The passed descriptor must have lifespan
316 * at least equal to the slot's. If it is a reference-counted descriptor
317 * then the reference count is incremented for as long as the slot holds
318 * a reference.
319 * --------------------------------
321 void
322 ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
323 TupleDesc tupdesc) /* new tuple descriptor */
325 /* For safety, make sure slot is empty before changing it */
326 ExecClearTuple(slot);
329 * Release any old descriptor. Also release old Datum/isnull arrays if
330 * present (we don't bother to check if they could be re-used).
332 if (slot->tts_tupleDescriptor)
333 ReleaseTupleDesc(slot->tts_tupleDescriptor);
335 if (slot->tts_values)
336 pfree(slot->tts_values);
337 if (slot->tts_isnull)
338 pfree(slot->tts_isnull);
341 * Install the new descriptor; if it's refcounted, bump its refcount.
343 slot->tts_tupleDescriptor = tupdesc;
344 PinTupleDesc(tupdesc);
347 * Allocate Datum/isnull arrays of the appropriate size. These must have
348 * the same lifetime as the slot, so allocate in the slot's own context.
350 slot->tts_values = (Datum *)
351 MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(Datum));
352 slot->tts_isnull = (bool *)
353 MemoryContextAlloc(slot->tts_mcxt, tupdesc->natts * sizeof(bool));
356 /* --------------------------------
357 * ExecStoreTuple
359 * This function is used to store a physical tuple into a specified
360 * slot in the tuple table.
362 * tuple: tuple to store
363 * slot: slot to store it in
364 * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer
365 * shouldFree: true if ExecClearTuple should pfree() the tuple
366 * when done with it
368 * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin
369 * on the buffer which is held until the slot is cleared, so that the tuple
370 * won't go away on us.
372 * shouldFree is normally set 'true' for tuples constructed on-the-fly.
373 * It must always be 'false' for tuples that are stored in disk pages,
374 * since we don't want to try to pfree those.
376 * Another case where it is 'false' is when the referenced tuple is held
377 * in a tuple table slot belonging to a lower-level executor Proc node.
378 * In this case the lower-level slot retains ownership and responsibility
379 * for eventually releasing the tuple. When this method is used, we must
380 * be certain that the upper-level Proc node will lose interest in the tuple
381 * sooner than the lower-level one does! If you're not certain, copy the
382 * lower-level tuple with heap_copytuple and let the upper-level table
383 * slot assume ownership of the copy!
385 * Return value is just the passed-in slot pointer.
387 * NOTE: before PostgreSQL 8.1, this function would accept a NULL tuple
388 * pointer and effectively behave like ExecClearTuple (though you could
389 * still specify a buffer to pin, which would be an odd combination).
390 * This saved a couple lines of code in a few places, but seemed more likely
391 * to mask logic errors than to be really useful, so it's now disallowed.
392 * --------------------------------
394 TupleTableSlot *
395 ExecStoreTuple(HeapTuple tuple,
396 TupleTableSlot *slot,
397 Buffer buffer,
398 bool shouldFree)
401 * sanity checks
403 Assert(tuple != NULL);
404 Assert(slot != NULL);
405 Assert(slot->tts_tupleDescriptor != NULL);
406 /* passing shouldFree=true for a tuple on a disk page is not sane */
407 Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
410 * Free any old physical tuple belonging to the slot.
412 if (slot->tts_shouldFree)
414 if (slot->tts_mintuple)
415 heap_free_minimal_tuple(slot->tts_mintuple);
416 else
417 heap_freetuple(slot->tts_tuple);
421 * Store the new tuple into the specified slot.
423 slot->tts_isempty = false;
424 slot->tts_shouldFree = shouldFree;
425 slot->tts_tuple = tuple;
426 slot->tts_mintuple = NULL;
428 /* Mark extracted state invalid */
429 slot->tts_nvalid = 0;
432 * If tuple is on a disk page, keep the page pinned as long as we hold a
433 * pointer into it. We assume the caller already has such a pin.
435 * This is coded to optimize the case where the slot previously held a
436 * tuple on the same disk page: in that case releasing and re-acquiring
437 * the pin is a waste of cycles. This is a common situation during
438 * seqscans, so it's worth troubling over.
440 if (slot->tts_buffer != buffer)
442 if (BufferIsValid(slot->tts_buffer))
443 ReleaseBuffer(slot->tts_buffer);
444 slot->tts_buffer = buffer;
445 if (BufferIsValid(buffer))
446 IncrBufferRefCount(buffer);
449 return slot;
452 /* --------------------------------
453 * ExecStoreMinimalTuple
455 * Like ExecStoreTuple, but insert a "minimal" tuple into the slot.
457 * No 'buffer' parameter since minimal tuples are never stored in relations.
458 * --------------------------------
460 TupleTableSlot *
461 ExecStoreMinimalTuple(MinimalTuple mtup,
462 TupleTableSlot *slot,
463 bool shouldFree)
466 * sanity checks
468 Assert(mtup != NULL);
469 Assert(slot != NULL);
470 Assert(slot->tts_tupleDescriptor != NULL);
473 * Free any old physical tuple belonging to the slot.
475 if (slot->tts_shouldFree)
477 if (slot->tts_mintuple)
478 heap_free_minimal_tuple(slot->tts_mintuple);
479 else
480 heap_freetuple(slot->tts_tuple);
484 * Drop the pin on the referenced buffer, if there is one.
486 if (BufferIsValid(slot->tts_buffer))
487 ReleaseBuffer(slot->tts_buffer);
489 slot->tts_buffer = InvalidBuffer;
492 * Store the new tuple into the specified slot.
494 slot->tts_isempty = false;
495 slot->tts_shouldFree = shouldFree;
496 slot->tts_tuple = &slot->tts_minhdr;
497 slot->tts_mintuple = mtup;
499 slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET;
500 slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET);
501 /* no need to set t_self or t_tableOid since we won't allow access */
503 /* Mark extracted state invalid */
504 slot->tts_nvalid = 0;
506 return slot;
509 /* --------------------------------
510 * ExecClearTuple
512 * This function is used to clear out a slot in the tuple table.
514 * NB: only the tuple is cleared, not the tuple descriptor (if any).
515 * --------------------------------
517 TupleTableSlot * /* return: slot passed */
518 ExecClearTuple(TupleTableSlot *slot) /* slot in which to store tuple */
521 * sanity checks
523 Assert(slot != NULL);
526 * Free the old physical tuple if necessary.
528 if (slot->tts_shouldFree)
530 if (slot->tts_mintuple)
531 heap_free_minimal_tuple(slot->tts_mintuple);
532 else
533 heap_freetuple(slot->tts_tuple);
536 slot->tts_tuple = NULL;
537 slot->tts_mintuple = NULL;
538 slot->tts_shouldFree = false;
541 * Drop the pin on the referenced buffer, if there is one.
543 if (BufferIsValid(slot->tts_buffer))
544 ReleaseBuffer(slot->tts_buffer);
546 slot->tts_buffer = InvalidBuffer;
549 * Mark it empty.
551 slot->tts_isempty = true;
552 slot->tts_nvalid = 0;
554 return slot;
557 /* --------------------------------
558 * ExecStoreVirtualTuple
559 * Mark a slot as containing a virtual tuple.
561 * The protocol for loading a slot with virtual tuple data is:
562 * * Call ExecClearTuple to mark the slot empty.
563 * * Store data into the Datum/isnull arrays.
564 * * Call ExecStoreVirtualTuple to mark the slot valid.
565 * This is a bit unclean but it avoids one round of data copying.
566 * --------------------------------
568 TupleTableSlot *
569 ExecStoreVirtualTuple(TupleTableSlot *slot)
572 * sanity checks
574 Assert(slot != NULL);
575 Assert(slot->tts_tupleDescriptor != NULL);
576 Assert(slot->tts_isempty);
578 slot->tts_isempty = false;
579 slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
581 return slot;
584 /* --------------------------------
585 * ExecStoreAllNullTuple
586 * Set up the slot to contain a null in every column.
588 * At first glance this might sound just like ExecClearTuple, but it's
589 * entirely different: the slot ends up full, not empty.
590 * --------------------------------
592 TupleTableSlot *
593 ExecStoreAllNullTuple(TupleTableSlot *slot)
596 * sanity checks
598 Assert(slot != NULL);
599 Assert(slot->tts_tupleDescriptor != NULL);
601 /* Clear any old contents */
602 ExecClearTuple(slot);
605 * Fill all the columns of the virtual tuple with nulls
607 MemSet(slot->tts_values, 0,
608 slot->tts_tupleDescriptor->natts * sizeof(Datum));
609 memset(slot->tts_isnull, true,
610 slot->tts_tupleDescriptor->natts * sizeof(bool));
612 return ExecStoreVirtualTuple(slot);
615 /* --------------------------------
616 * ExecCopySlotTuple
617 * Obtain a copy of a slot's regular physical tuple. The copy is
618 * palloc'd in the current memory context.
620 * This works even if the slot contains a virtual or minimal tuple;
621 * however the "system columns" of the result will not be meaningful.
622 * --------------------------------
624 HeapTuple
625 ExecCopySlotTuple(TupleTableSlot *slot)
628 * sanity checks
630 Assert(slot != NULL);
631 Assert(!slot->tts_isempty);
634 * If we have a physical tuple then just copy it.
636 if (slot->tts_tuple)
638 if (slot->tts_mintuple)
639 return heap_tuple_from_minimal_tuple(slot->tts_mintuple);
640 else
641 return heap_copytuple(slot->tts_tuple);
645 * Otherwise we need to build a tuple from the Datum array.
647 return heap_form_tuple(slot->tts_tupleDescriptor,
648 slot->tts_values,
649 slot->tts_isnull);
652 /* --------------------------------
653 * ExecCopySlotMinimalTuple
654 * Obtain a copy of a slot's minimal physical tuple. The copy is
655 * palloc'd in the current memory context.
656 * --------------------------------
658 MinimalTuple
659 ExecCopySlotMinimalTuple(TupleTableSlot *slot)
662 * sanity checks
664 Assert(slot != NULL);
665 Assert(!slot->tts_isempty);
668 * If we have a physical tuple then just copy it.
670 if (slot->tts_tuple)
672 if (slot->tts_mintuple)
673 return heap_copy_minimal_tuple(slot->tts_mintuple);
674 else
675 return minimal_tuple_from_heap_tuple(slot->tts_tuple);
679 * Otherwise we need to build a tuple from the Datum array.
681 return heap_form_minimal_tuple(slot->tts_tupleDescriptor,
682 slot->tts_values,
683 slot->tts_isnull);
686 /* --------------------------------
687 * ExecFetchSlotTuple
688 * Fetch the slot's regular physical tuple.
690 * If the slot contains a virtual tuple, we convert it to physical
691 * form. The slot retains ownership of the physical tuple.
692 * Likewise, if it contains a minimal tuple we convert to regular form.
694 * The difference between this and ExecMaterializeSlot() is that this
695 * does not guarantee that the contained tuple is local storage.
696 * Hence, the result must be treated as read-only.
697 * --------------------------------
699 HeapTuple
700 ExecFetchSlotTuple(TupleTableSlot *slot)
703 * sanity checks
705 Assert(slot != NULL);
706 Assert(!slot->tts_isempty);
709 * If we have a regular physical tuple then just return it.
711 if (slot->tts_tuple && slot->tts_mintuple == NULL)
712 return slot->tts_tuple;
715 * Otherwise materialize the slot...
717 return ExecMaterializeSlot(slot);
720 /* --------------------------------
721 * ExecFetchSlotMinimalTuple
722 * Fetch the slot's minimal physical tuple.
724 * If the slot contains a virtual tuple, we convert it to minimal
725 * physical form. The slot retains ownership of the physical tuple.
726 * Likewise, if it contains a regular tuple we convert to minimal form.
728 * As above, the result must be treated as read-only.
729 * --------------------------------
731 MinimalTuple
732 ExecFetchSlotMinimalTuple(TupleTableSlot *slot)
734 MinimalTuple newTuple;
735 MemoryContext oldContext;
738 * sanity checks
740 Assert(slot != NULL);
741 Assert(!slot->tts_isempty);
744 * If we have a minimal physical tuple then just return it.
746 if (slot->tts_mintuple)
747 return slot->tts_mintuple;
750 * Otherwise, build a minimal tuple, and then store it as the new slot
751 * value. (Note: tts_nvalid will be reset to zero here. There are cases
752 * in which this could be optimized but it's probably not worth worrying
753 * about.)
755 * We may be called in a context that is shorter-lived than the tuple
756 * slot, but we have to ensure that the materialized tuple will survive
757 * anyway.
759 oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
760 newTuple = ExecCopySlotMinimalTuple(slot);
761 MemoryContextSwitchTo(oldContext);
763 ExecStoreMinimalTuple(newTuple, slot, true);
765 Assert(slot->tts_mintuple);
766 return slot->tts_mintuple;
769 /* --------------------------------
770 * ExecFetchSlotTupleDatum
771 * Fetch the slot's tuple as a composite-type Datum.
773 * We convert the slot's contents to local physical-tuple form,
774 * and fill in the Datum header fields. Note that the result
775 * always points to storage owned by the slot.
776 * --------------------------------
778 Datum
779 ExecFetchSlotTupleDatum(TupleTableSlot *slot)
781 HeapTuple tup;
782 HeapTupleHeader td;
783 TupleDesc tupdesc;
785 /* Make sure we can scribble on the slot contents ... */
786 tup = ExecMaterializeSlot(slot);
787 /* ... and set up the composite-Datum header fields, in case not done */
788 td = tup->t_data;
789 tupdesc = slot->tts_tupleDescriptor;
790 HeapTupleHeaderSetDatumLength(td, tup->t_len);
791 HeapTupleHeaderSetTypeId(td, tupdesc->tdtypeid);
792 HeapTupleHeaderSetTypMod(td, tupdesc->tdtypmod);
793 return PointerGetDatum(td);
796 /* --------------------------------
797 * ExecMaterializeSlot
798 * Force a slot into the "materialized" state.
800 * This causes the slot's tuple to be a local copy not dependent on
801 * any external storage. A pointer to the contained tuple is returned.
803 * A typical use for this operation is to prepare a computed tuple
804 * for being stored on disk. The original data may or may not be
805 * virtual, but in any case we need a private copy for heap_insert
806 * to scribble on.
807 * --------------------------------
809 HeapTuple
810 ExecMaterializeSlot(TupleTableSlot *slot)
812 HeapTuple newTuple;
813 MemoryContext oldContext;
816 * sanity checks
818 Assert(slot != NULL);
819 Assert(!slot->tts_isempty);
822 * If we have a regular physical tuple, and it's locally palloc'd, we have
823 * nothing to do.
825 if (slot->tts_tuple && slot->tts_shouldFree && slot->tts_mintuple == NULL)
826 return slot->tts_tuple;
829 * Otherwise, copy or build a tuple, and then store it as the new slot
830 * value. (Note: tts_nvalid will be reset to zero here. There are cases
831 * in which this could be optimized but it's probably not worth worrying
832 * about.)
834 * We may be called in a context that is shorter-lived than the tuple
835 * slot, but we have to ensure that the materialized tuple will survive
836 * anyway.
838 oldContext = MemoryContextSwitchTo(slot->tts_mcxt);
839 newTuple = ExecCopySlotTuple(slot);
840 MemoryContextSwitchTo(oldContext);
842 ExecStoreTuple(newTuple, slot, InvalidBuffer, true);
844 return slot->tts_tuple;
847 /* --------------------------------
848 * ExecCopySlot
849 * Copy the source slot's contents into the destination slot.
851 * The destination acquires a private copy that will not go away
852 * if the source is cleared.
854 * The caller must ensure the slots have compatible tupdescs.
855 * --------------------------------
857 TupleTableSlot *
858 ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
860 HeapTuple newTuple;
861 MemoryContext oldContext;
864 * There might be ways to optimize this when the source is virtual, but
865 * for now just always build a physical copy. Make sure it is in the
866 * right context.
868 oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt);
869 newTuple = ExecCopySlotTuple(srcslot);
870 MemoryContextSwitchTo(oldContext);
872 return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true);
876 /* ----------------------------------------------------------------
877 * convenience initialization routines
878 * ----------------------------------------------------------------
881 /* --------------------------------
882 * ExecInit{Result,Scan,Extra}TupleSlot
884 * These are convenience routines to initialize the specified slot
885 * in nodes inheriting the appropriate state. ExecInitExtraTupleSlot
886 * is used for initializing special-purpose slots.
887 * --------------------------------
890 /* ----------------
891 * ExecInitResultTupleSlot
892 * ----------------
894 void
895 ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
897 planstate->ps_ResultTupleSlot = ExecAllocTableSlot(estate->es_tupleTable);
900 /* ----------------
901 * ExecInitScanTupleSlot
902 * ----------------
904 void
905 ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
907 scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(estate->es_tupleTable);
910 /* ----------------
911 * ExecInitExtraTupleSlot
912 * ----------------
914 TupleTableSlot *
915 ExecInitExtraTupleSlot(EState *estate)
917 return ExecAllocTableSlot(estate->es_tupleTable);
920 /* ----------------
921 * ExecInitNullTupleSlot
923 * Build a slot containing an all-nulls tuple of the given type.
924 * This is used as a substitute for an input tuple when performing an
925 * outer join.
926 * ----------------
928 TupleTableSlot *
929 ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
931 TupleTableSlot *slot = ExecInitExtraTupleSlot(estate);
933 ExecSetSlotDescriptor(slot, tupType);
935 return ExecStoreAllNullTuple(slot);
938 /* ----------------------------------------------------------------
939 * ExecTypeFromTL
941 * Generate a tuple descriptor for the result tuple of a targetlist.
942 * (A parse/plan tlist must be passed, not an ExprState tlist.)
943 * Note that resjunk columns, if any, are included in the result.
945 * Currently there are about 4 different places where we create
946 * TupleDescriptors. They should all be merged, or perhaps
947 * be rewritten to call BuildDesc().
948 * ----------------------------------------------------------------
950 TupleDesc
951 ExecTypeFromTL(List *targetList, bool hasoid)
953 return ExecTypeFromTLInternal(targetList, hasoid, false);
956 /* ----------------------------------------------------------------
957 * ExecCleanTypeFromTL
959 * Same as above, but resjunk columns are omitted from the result.
960 * ----------------------------------------------------------------
962 TupleDesc
963 ExecCleanTypeFromTL(List *targetList, bool hasoid)
965 return ExecTypeFromTLInternal(targetList, hasoid, true);
968 static TupleDesc
969 ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
971 TupleDesc typeInfo;
972 ListCell *l;
973 int len;
974 int cur_resno = 1;
976 if (skipjunk)
977 len = ExecCleanTargetListLength(targetList);
978 else
979 len = ExecTargetListLength(targetList);
980 typeInfo = CreateTemplateTupleDesc(len, hasoid);
982 foreach(l, targetList)
984 TargetEntry *tle = lfirst(l);
986 if (skipjunk && tle->resjunk)
987 continue;
988 TupleDescInitEntry(typeInfo,
989 cur_resno++,
990 tle->resname,
991 exprType((Node *) tle->expr),
992 exprTypmod((Node *) tle->expr),
996 return typeInfo;
1000 * ExecTypeFromExprList - build a tuple descriptor from a list of Exprs
1002 * Here we must make up an arbitrary set of field names.
1004 TupleDesc
1005 ExecTypeFromExprList(List *exprList)
1007 TupleDesc typeInfo;
1008 ListCell *l;
1009 int cur_resno = 1;
1010 char fldname[NAMEDATALEN];
1012 typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
1014 foreach(l, exprList)
1016 Node *e = lfirst(l);
1018 sprintf(fldname, "f%d", cur_resno);
1020 TupleDescInitEntry(typeInfo,
1021 cur_resno++,
1022 fldname,
1023 exprType(e),
1024 exprTypmod(e),
1028 return typeInfo;
1032 * BlessTupleDesc - make a completed tuple descriptor useful for SRFs
1034 * Rowtype Datums returned by a function must contain valid type information.
1035 * This happens "for free" if the tupdesc came from a relcache entry, but
1036 * not if we have manufactured a tupdesc for a transient RECORD datatype.
1037 * In that case we have to notify typcache.c of the existence of the type.
1039 TupleDesc
1040 BlessTupleDesc(TupleDesc tupdesc)
1042 if (tupdesc->tdtypeid == RECORDOID &&
1043 tupdesc->tdtypmod < 0)
1044 assign_record_type_typmod(tupdesc);
1046 return tupdesc; /* just for notational convenience */
1050 * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc
1052 * Note: this is obsolete; it is sufficient to call BlessTupleDesc on
1053 * the tupdesc. We keep it around just for backwards compatibility with
1054 * existing user-written SRFs.
1056 TupleTableSlot *
1057 TupleDescGetSlot(TupleDesc tupdesc)
1059 TupleTableSlot *slot;
1061 /* The useful work is here */
1062 BlessTupleDesc(tupdesc);
1064 /* Make a standalone slot */
1065 slot = MakeSingleTupleTableSlot(tupdesc);
1067 /* Return the slot */
1068 return slot;
1072 * TupleDescGetAttInMetadata - Build an AttInMetadata structure based on the
1073 * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
1074 * to produce a properly formed tuple.
1076 AttInMetadata *
1077 TupleDescGetAttInMetadata(TupleDesc tupdesc)
1079 int natts = tupdesc->natts;
1080 int i;
1081 Oid atttypeid;
1082 Oid attinfuncid;
1083 FmgrInfo *attinfuncinfo;
1084 Oid *attioparams;
1085 int32 *atttypmods;
1086 AttInMetadata *attinmeta;
1088 attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
1090 /* "Bless" the tupledesc so that we can make rowtype datums with it */
1091 attinmeta->tupdesc = BlessTupleDesc(tupdesc);
1094 * Gather info needed later to call the "in" function for each attribute
1096 attinfuncinfo = (FmgrInfo *) palloc0(natts * sizeof(FmgrInfo));
1097 attioparams = (Oid *) palloc0(natts * sizeof(Oid));
1098 atttypmods = (int32 *) palloc0(natts * sizeof(int32));
1100 for (i = 0; i < natts; i++)
1102 /* Ignore dropped attributes */
1103 if (!tupdesc->attrs[i]->attisdropped)
1105 atttypeid = tupdesc->attrs[i]->atttypid;
1106 getTypeInputInfo(atttypeid, &attinfuncid, &attioparams[i]);
1107 fmgr_info(attinfuncid, &attinfuncinfo[i]);
1108 atttypmods[i] = tupdesc->attrs[i]->atttypmod;
1111 attinmeta->attinfuncs = attinfuncinfo;
1112 attinmeta->attioparams = attioparams;
1113 attinmeta->atttypmods = atttypmods;
1115 return attinmeta;
1119 * BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
1120 * values is an array of C strings, one for each attribute of the return tuple.
1121 * A NULL string pointer indicates we want to create a NULL field.
1123 HeapTuple
1124 BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
1126 TupleDesc tupdesc = attinmeta->tupdesc;
1127 int natts = tupdesc->natts;
1128 Datum *dvalues;
1129 char *nulls;
1130 int i;
1131 HeapTuple tuple;
1133 dvalues = (Datum *) palloc(natts * sizeof(Datum));
1134 nulls = (char *) palloc(natts * sizeof(char));
1136 /* Call the "in" function for each non-dropped attribute */
1137 for (i = 0; i < natts; i++)
1139 if (!tupdesc->attrs[i]->attisdropped)
1141 /* Non-dropped attributes */
1142 dvalues[i] = InputFunctionCall(&attinmeta->attinfuncs[i],
1143 values[i],
1144 attinmeta->attioparams[i],
1145 attinmeta->atttypmods[i]);
1146 if (values[i] != NULL)
1147 nulls[i] = ' ';
1148 else
1149 nulls[i] = 'n';
1151 else
1153 /* Handle dropped attributes by setting to NULL */
1154 dvalues[i] = (Datum) 0;
1155 nulls[i] = 'n';
1160 * Form a tuple
1162 tuple = heap_formtuple(tupdesc, dvalues, nulls);
1165 * Release locally palloc'd space. XXX would probably be good to pfree
1166 * values of pass-by-reference datums, as well.
1168 pfree(dvalues);
1169 pfree(nulls);
1171 return tuple;
1175 * Functions for sending tuples to the frontend (or other specified destination)
1176 * as though it is a SELECT result. These are used by utility commands that
1177 * need to project directly to the destination and don't need or want full
1178 * Table Function capability. Currently used by EXPLAIN and SHOW ALL
1180 TupOutputState *
1181 begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc)
1183 TupOutputState *tstate;
1185 tstate = (TupOutputState *) palloc(sizeof(TupOutputState));
1187 tstate->metadata = TupleDescGetAttInMetadata(tupdesc);
1188 tstate->slot = MakeSingleTupleTableSlot(tupdesc);
1189 tstate->dest = dest;
1191 (*tstate->dest->rStartup) (tstate->dest, (int) CMD_SELECT, tupdesc);
1193 return tstate;
1197 * write a single tuple
1199 * values is a list of the external C string representations of the values
1200 * to be projected.
1202 * XXX This could be made more efficient, since in reality we probably only
1203 * need a virtual tuple.
1205 void
1206 do_tup_output(TupOutputState *tstate, char **values)
1208 /* build a tuple from the input strings using the tupdesc */
1209 HeapTuple tuple = BuildTupleFromCStrings(tstate->metadata, values);
1211 /* put it in a slot */
1212 ExecStoreTuple(tuple, tstate->slot, InvalidBuffer, true);
1214 /* send the tuple to the receiver */
1215 (*tstate->dest->receiveSlot) (tstate->slot, tstate->dest);
1217 /* clean up */
1218 ExecClearTuple(tstate->slot);
1222 * write a chunk of text, breaking at newline characters
1224 * NB: scribbles on its input!
1226 * Should only be used with a single-TEXT-attribute tupdesc.
1228 void
1229 do_text_output_multiline(TupOutputState *tstate, char *text)
1231 while (*text)
1233 char *eol;
1235 eol = strchr(text, '\n');
1236 if (eol)
1237 *eol++ = '\0';
1238 else
1239 eol = text +strlen(text);
1241 do_tup_output(tstate, &text);
1242 text = eol;
1246 void
1247 end_tup_output(TupOutputState *tstate)
1249 (*tstate->dest->rShutdown) (tstate->dest);
1250 /* note that destroying the dest is not ours to do */
1251 ExecDropSingleTupleTableSlot(tstate->slot);
1252 /* XXX worth cleaning up the attinmetadata? */
1253 pfree(tstate);