1 /*-------------------------------------------------------------------------
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
20 *-------------------------------------------------------------------------
26 * ExecCreateTupleTable - create a new tuple table
27 * ExecDropTupleTable - destroy a table
28 * MakeSingleTupleTableSlot - make a single-slot table
29 * ExecDropSingleTupleTableSlot - destroy same
32 * ExecAllocTableSlot - find an available slot in the table
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.
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()
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.
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.
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 * --------------------------------
121 ExecCreateTupleTable(int tableSize
)
129 Assert(tableSize
>= 1);
132 * allocate the table itself
134 newtable
= (TupleTable
) palloc(sizeof(TupleTableData
) +
135 (tableSize
- 1) *sizeof(TupleTableSlot
));
136 newtable
->size
= tableSize
;
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
;
162 /* --------------------------------
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 * --------------------------------
171 ExecDropTupleTable(TupleTable table
, /* tuple table */
172 bool shouldFree
) /* true if we should free slot
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!)
187 int next
= table
->next
;
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.
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 * --------------------------------
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
);
241 /* --------------------------------
242 * ExecDropSingleTupleTableSlot
244 * Release a TupleTableSlot made with MakeSingleTupleTableSlot.
245 * --------------------------------
248 ExecDropSingleTupleTableSlot(TupleTableSlot
*slot
)
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
);
267 /* ----------------------------------------------------------------
268 * tuple table slot reservation functions
269 * ----------------------------------------------------------------
272 /* --------------------------------
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 * --------------------------------
283 ExecAllocTableSlot(TupleTable table
)
285 int slotnum
; /* new slot number */
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
;
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
319 * --------------------------------
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 /* --------------------------------
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
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 * --------------------------------
395 ExecStoreTuple(HeapTuple tuple
,
396 TupleTableSlot
*slot
,
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
);
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
);
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 * --------------------------------
461 ExecStoreMinimalTuple(MinimalTuple mtup
,
462 TupleTableSlot
*slot
,
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
);
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;
509 /* --------------------------------
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 */
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
);
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
;
551 slot
->tts_isempty
= true;
552 slot
->tts_nvalid
= 0;
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 * --------------------------------
569 ExecStoreVirtualTuple(TupleTableSlot
*slot
)
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
;
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 * --------------------------------
593 ExecStoreAllNullTuple(TupleTableSlot
*slot
)
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 /* --------------------------------
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 * --------------------------------
625 ExecCopySlotTuple(TupleTableSlot
*slot
)
630 Assert(slot
!= NULL
);
631 Assert(!slot
->tts_isempty
);
634 * If we have a physical tuple then just copy it.
638 if (slot
->tts_mintuple
)
639 return heap_tuple_from_minimal_tuple(slot
->tts_mintuple
);
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
,
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 * --------------------------------
659 ExecCopySlotMinimalTuple(TupleTableSlot
*slot
)
664 Assert(slot
!= NULL
);
665 Assert(!slot
->tts_isempty
);
668 * If we have a physical tuple then just copy it.
672 if (slot
->tts_mintuple
)
673 return heap_copy_minimal_tuple(slot
->tts_mintuple
);
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
,
686 /* --------------------------------
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 * --------------------------------
700 ExecFetchSlotTuple(TupleTableSlot
*slot
)
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 * --------------------------------
732 ExecFetchSlotMinimalTuple(TupleTableSlot
*slot
)
734 MinimalTuple newTuple
;
735 MemoryContext oldContext
;
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
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
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 * --------------------------------
779 ExecFetchSlotTupleDatum(TupleTableSlot
*slot
)
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 */
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
807 * --------------------------------
810 ExecMaterializeSlot(TupleTableSlot
*slot
)
813 MemoryContext oldContext
;
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
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
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
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 /* --------------------------------
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 * --------------------------------
858 ExecCopySlot(TupleTableSlot
*dstslot
, TupleTableSlot
*srcslot
)
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
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 * --------------------------------
891 * ExecInitResultTupleSlot
895 ExecInitResultTupleSlot(EState
*estate
, PlanState
*planstate
)
897 planstate
->ps_ResultTupleSlot
= ExecAllocTableSlot(estate
->es_tupleTable
);
901 * ExecInitScanTupleSlot
905 ExecInitScanTupleSlot(EState
*estate
, ScanState
*scanstate
)
907 scanstate
->ss_ScanTupleSlot
= ExecAllocTableSlot(estate
->es_tupleTable
);
911 * ExecInitExtraTupleSlot
915 ExecInitExtraTupleSlot(EState
*estate
)
917 return ExecAllocTableSlot(estate
->es_tupleTable
);
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
929 ExecInitNullTupleSlot(EState
*estate
, TupleDesc tupType
)
931 TupleTableSlot
*slot
= ExecInitExtraTupleSlot(estate
);
933 ExecSetSlotDescriptor(slot
, tupType
);
935 return ExecStoreAllNullTuple(slot
);
938 /* ----------------------------------------------------------------
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 * ----------------------------------------------------------------
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 * ----------------------------------------------------------------
963 ExecCleanTypeFromTL(List
*targetList
, bool hasoid
)
965 return ExecTypeFromTLInternal(targetList
, hasoid
, true);
969 ExecTypeFromTLInternal(List
*targetList
, bool hasoid
, bool skipjunk
)
977 len
= ExecCleanTargetListLength(targetList
);
979 len
= ExecTargetListLength(targetList
);
980 typeInfo
= CreateTemplateTupleDesc(len
, hasoid
);
982 foreach(l
, targetList
)
984 TargetEntry
*tle
= lfirst(l
);
986 if (skipjunk
&& tle
->resjunk
)
988 TupleDescInitEntry(typeInfo
,
991 exprType((Node
*) tle
->expr
),
992 exprTypmod((Node
*) tle
->expr
),
1000 * ExecTypeFromExprList - build a tuple descriptor from a list of Exprs
1002 * Here we must make up an arbitrary set of field names.
1005 ExecTypeFromExprList(List
*exprList
)
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
,
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.
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.
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 */
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.
1077 TupleDescGetAttInMetadata(TupleDesc tupdesc
)
1079 int natts
= tupdesc
->natts
;
1083 FmgrInfo
*attinfuncinfo
;
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
;
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.
1124 BuildTupleFromCStrings(AttInMetadata
*attinmeta
, char **values
)
1126 TupleDesc tupdesc
= attinmeta
->tupdesc
;
1127 int natts
= tupdesc
->natts
;
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
],
1144 attinmeta
->attioparams
[i
],
1145 attinmeta
->atttypmods
[i
]);
1146 if (values
[i
] != NULL
)
1153 /* Handle dropped attributes by setting to NULL */
1154 dvalues
[i
] = (Datum
) 0;
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.
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
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
);
1197 * write a single tuple
1199 * values is a list of the external C string representations of the values
1202 * XXX This could be made more efficient, since in reality we probably only
1203 * need a virtual tuple.
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
);
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.
1229 do_text_output_multiline(TupOutputState
*tstate
, char *text
)
1235 eol
= strchr(text
, '\n');
1239 eol
= text
+strlen(text
);
1241 do_tup_output(tstate
, &text
);
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? */