Add slot-based table AM index scan interface. Add table_index_getnext_slot, a new table AM interface that serves as the single entry point for both plain and index-only index scans that use amgettuple. The table AM's index_scan_begin callback resolves which implementation the scan will use and stores it in an IndexScanDesc function pointer (xs_getnext_slot), which table_index_getnext_slot dispatches through.
The interface intentionally avoids using fixed TableAmRoutine members, allowing the table AM to dynamically register an implementation based on conditions known at the start of each scan. That way a table AM can provide specialized variants that help the compiler produce more efficient code. heapam provides two implementations: one for plain index scans, and one for index-only scans. An upcoming commit that adds the amgetbatch interface will add two more. (Table AMs can opt to provide a single generic implementation, or to provide many specialized implementations, as requirements dictate.) heapam's xs_getnext_slot implementations make aggressive use of forced inlining to ensure that plain and index-only code paths are fully specialized at compile time, without duplicating the code they have in common. This specialization is necessary to keep icache and iTLB pressure to a minimum. The new interface moves visibility map checks required by index-only scans out of the executor (and selfuncs.c) and into heapam, enabling batching of visibility map lookups (though for now we continue to just perform retail lookups). Using the new higher level slot-based interface greatly simplifies nodeIndexonlyscan.c, which no longer has to deal with the visibility map directly. More importantly, this is a significant architectural improvement: table AMs can now implement index-only scans that are not tied to heapam's visibility map. Two users of the now removed table_index_fetch_tuple interface, _bt_check_unique and unique_key_recheck, fundamentally need to pass a TID to the table AM to perform constraint enforcement. Neither actually performs an index scan (even though their TIDs are taken from an index), so neither has any use for most of the index scan machinery. Switch these callers over to fetch_tid, a new special-purpose table AM interface for constraint enforcement code. All true index scan callers now use the new slot-based interface. (Note that fetch_tid doesn't perform on-access pruning, which matches how things worked prior to Postgres 12 commits c2fe139c2 and 71bdc99d0.) The VISITED_PAGES_LIMIT mechanism used by get_actual_variable_range to cap scan overhead during planning is reworked to go through a new scan descriptor field (xs_visited_pages_limit), rather than having selfuncs.c count heap page fetches and terminate the scan itself. This is necessary because callers that use the new slot-based interface no longer have direct access to which heap blocks were fetched. Similarly, nodeIndexonlyscan.c can no longer use InstrCountTuples2 to count heap fetches during an EXPLAIN ANALYZE. EXPLAIN ANALYZE now obtains this information from a new IndexScanInstrumentation field, which table AMs are required to maintain during index-only scans. Though independently useful, this commit is preparatory work for an upcoming commit that will add an amgetbatch index AM interface, where the table AM takes full responsibility for managing the progress of index scans. The table AM determines when to request the next batch from the index AM, at a time of its choosing. A follow-on commit will rely on this to prefetch table blocks during index scans. Having a single entry point for all index scan callers unambiguously puts the table AM in control of the scan. Author: Peter Geoghegan <[email protected]> Reviewed-by: Andres Freund <[email protected]> Reviewed-by: Tomas Vondra <[email protected]> Reviewed-by: Rui Zhao <[email protected]> Discussion: https://postgr.es/m/CAH2-WzmYqhacBH161peAWb5eF=Ja7CFAQ+0jSEMq=qnflvt...@mail.gmail.com Branch ------ master Details ------- https://git.postgresql.org/pg/commitdiff/ddce1da5b1b1b4672e621c0da245e01474cbd4e8 Modified Files -------------- contrib/amcheck/verify_nbtree.c | 2 +- src/backend/access/heap/heapam_handler.c | 13 +- src/backend/access/heap/heapam_indexscan.c | 365 ++++++++++++++++++++++++--- src/backend/access/index/genam.c | 29 ++- src/backend/access/index/indexam.c | 297 +++++++--------------- src/backend/access/nbtree/nbtinsert.c | 8 +- src/backend/access/table/Makefile | 1 + src/backend/access/table/meson.build | 1 + src/backend/access/table/tableam.c | 38 --- src/backend/access/table/tableam_indexscan.c | 49 ++++ src/backend/access/table/tableamapi.c | 8 +- src/backend/commands/constraint.c | 37 +-- src/backend/commands/explain.c | 23 +- src/backend/commands/repack.c | 4 +- src/backend/executor/execIndexing.c | 5 +- src/backend/executor/execReplication.c | 8 +- src/backend/executor/nodeBitmapIndexscan.c | 1 + src/backend/executor/nodeIndexonlyscan.c | 231 +---------------- src/backend/executor/nodeIndexscan.c | 9 +- src/backend/utils/adt/ri_triggers.c | 8 +- src/backend/utils/adt/selfuncs.c | 94 ++----- src/include/access/genam.h | 7 +- src/include/access/heapam.h | 27 +- src/include/access/relscan.h | 58 +++-- src/include/access/tableam.h | 204 ++++++++------- src/include/access/tableam_indexscan.h | 112 ++++++++ src/include/catalog/pg_opclass.dat | 4 +- src/include/executor/instrument_node.h | 5 +- src/include/nodes/execnodes.h | 8 - src/test/modules/index/test_indexscan.c | 4 +- src/tools/pgindent/typedefs.list | 3 +- 31 files changed, 868 insertions(+), 795 deletions(-)
