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