Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * tableam_indexscan.h
4 : : * Helpers for table AM index scan callbacks.
5 : : *
6 : : * Table AMs can use these functions to implement xs_getnext_slot callbacks.
7 : : * See access/tableam.h.
8 : : *
9 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
10 : : * Portions Copyright (c) 1994, Regents of the University of California
11 : : *
12 : : * src/include/access/tableam_indexscan.h
13 : : *
14 : : *-------------------------------------------------------------------------
15 : : */
16 : : #ifndef TABLEAM_INDEXSCAN_H
17 : : #define TABLEAM_INDEXSCAN_H
18 : :
19 : : #include "access/amapi.h"
20 : : #include "access/genam.h"
21 : : #include "access/relscan.h"
22 : : #include "executor/tuptable.h"
23 : : #include "pgstat.h"
24 : : #include "utils/rel.h"
25 : :
26 : : extern pg_attribute_cold void tableam_index_fill_ios_names(IndexScanDesc scan,
27 : : TupleTableSlot *slot);
28 : :
29 : :
30 : : /*
31 : : * Fetch the next matching TID for the scan (or the first) through the
32 : : * amgettuple interface.
33 : : *
34 : : * Returns true when a TID was found (the index AM will have saved it in
35 : : * scan->xs_heaptid), or false when we're out of index entries.
36 : : */
37 : : static inline bool
5 pg@bowt.ie 38 :GNC 22691777 : tableam_index_getnext_tid(IndexScanDesc scan, ScanDirection direction)
39 : : {
40 : : bool found;
41 : :
42 : 22691777 : found = scan->indexRelation->rd_indam->amgettuple(scan, direction);
43 : :
44 : : /* Reset kill flag immediately for safety */
45 : 22691777 : scan->kill_prior_tuple = false;
46 : 22691777 : scan->xs_heap_continue = false;
47 : :
48 : : /* If we're out of index entries, we're done */
49 [ + + ]: 22691777 : if (!found)
50 : 4359296 : return false;
51 : :
52 [ - + ]: 18332481 : Assert(ItemPointerIsValid(&scan->xs_heaptid));
53 : :
54 [ + + - + : 18332481 : pgstat_count_index_tuples(scan->indexRelation, 1);
+ + - + ]
55 : :
56 : 18332481 : return true;
57 : : }
58 : :
59 : : /*
60 : : * Fill an index-only scan's result slot from the data the index AM returned.
61 : : *
62 : : * The data is provided in either HeapTuple (xs_hitup) or IndexTuple (xs_itup)
63 : : * format. An index AM may fill both, in which case the heap format is used,
64 : : * since it's a bit cheaper to fill a slot from.
65 : : *
66 : : * Called by table AMs from their xs_getnext_slot callbacks.
67 : : */
68 : : static inline void
69 : 3820725 : tableam_index_fill_ios_slot(IndexScanDesc scan, TupleTableSlot *slot)
70 : : {
71 : 3820725 : ExecClearTuple(slot);
72 : :
73 : : /*
74 : : * We must deform the tuple using the tupdesc the index AM formed it with
75 : : * (xs_hitupdesc or xs_itupdesc), not the slot's tupdesc. The datums
76 : : * returned by the index AM must be binary compatible, but the descriptors
77 : : * may align each column differently in certain rare cases. (Actually,
78 : : * btree's "name" opclass stores cstring tuples that _aren't_ even binary
79 : : * compatible, in the strictest sense. tableam_index_fill_ios_names
80 : : * handles that.)
81 : : */
82 [ + + ]: 3820725 : if (scan->xs_hitup)
83 : : {
84 [ - + ]: 969066 : Assert(slot->tts_tupleDescriptor->natts == scan->xs_hitupdesc->natts);
85 : :
86 : 969066 : heap_deform_tuple(scan->xs_hitup, scan->xs_hitupdesc,
87 : : slot->tts_values, slot->tts_isnull);
88 : : }
89 [ + - ]: 2851659 : else if (scan->xs_itup)
90 : : {
91 [ - + ]: 2851659 : Assert(slot->tts_tupleDescriptor->natts == scan->xs_itupdesc->natts);
92 : :
93 : 2851659 : index_deform_tuple(scan->xs_itup, scan->xs_itupdesc,
94 : : slot->tts_values, slot->tts_isnull);
95 : :
96 : : /*
97 : : * Copy all name columns stored as cstrings back into NAMEDATALEN
98 : : * bytes of xs_name_cstring_buf. We mark this branch as unlikely as
99 : : * generally "name" is used only for the system catalogs and this
100 : : * would have to be a user query running on those or some other user
101 : : * table with an index on a name column.
102 : : */
103 [ + + ]: 2851659 : if (unlikely(scan->xs_name_cstring_attnums != NULL))
104 : 7655 : tableam_index_fill_ios_names(scan, slot);
105 : : }
106 : : else
5 pg@bowt.ie 107 [ # # ]:UNC 0 : elog(ERROR, "no data returned for index-only scan");
108 : :
5 pg@bowt.ie 109 :GNC 3820725 : ExecStoreVirtualTuple(slot);
110 : 3820725 : }
111 : :
112 : : #endif /* TABLEAM_INDEXSCAN_H */
|