v18-0001-Move-heapam_handler.c-index-scan-code-to-new-fil.patch
application/octet-stream
Filename: v18-0001-Move-heapam_handler.c-index-scan-code-to-new-fil.patch
Type: application/octet-stream
Part: 18
Message:
Re: index prefetching
Patch
Format: format-patch
Series: patch v18-0001
Subject: Move heapam_handler.c index scan code to new file.
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam_handler.c | 0 | 109 |
| src/backend/access/heap/heapam_indexscan.c | 126 | 0 |
| src/backend/access/heap/Makefile | 1 | 0 |
| src/backend/access/heap/meson.build | 1 | 0 |
| src/include/access/heapam.h | 9 | 0 |
From ce735ea792bdf40dddf1d38b64c48da1f37e3fdc Mon Sep 17 00:00:00 2001
From: Peter Geoghegan <pg@bowt.ie>
Date: Wed, 25 Mar 2026 00:22:17 -0400
Subject: [PATCH v18 01/19] Move heapam_handler.c index scan code to new file.
Move the heapam index fetch callbacks (index_fetch_begin,
index_fetch_reset, index_fetch_end, and index_fetch_tuple) into a
dedicated file. This is a purely mechanical move with no functional
changes.
Upcoming work to add a slot-based table AM interface for index scans
will substantially expand this code. Keeping it in heapam_handler.c
would clutter a file whose primary role is to wire up the TableAmRoutine
callbacks. Bitmap heap scans and sequential scans would benefit from
similar separation in the future.
Author: Peter Geoghegan <pg@bowt.ie>
Reviewed-By: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/bmbrkiyjxoal6o5xadzv5bveoynrt3x37wqch7w3jnwumkq2yo@b4zmtnrfs4mh
---
src/include/access/heapam.h | 9 ++
src/backend/access/heap/Makefile | 1 +
src/backend/access/heap/heapam_handler.c | 109 ------------------
src/backend/access/heap/heapam_indexscan.c | 126 +++++++++++++++++++++
src/backend/access/heap/meson.build | 1 +
5 files changed, 137 insertions(+), 109 deletions(-)
create mode 100644 src/backend/access/heap/heapam_indexscan.c
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 9b4032030..62f15e0b1 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -432,6 +432,15 @@ extern void simple_heap_update(Relation relation, const ItemPointerData *otid,
extern TransactionId heap_index_delete_tuples(Relation rel,
TM_IndexDeleteOp *delstate);
+/* in heap/heapam_indexscan.c */
+extern IndexFetchTableData *heapam_index_fetch_begin(Relation rel);
+extern void heapam_index_fetch_reset(IndexFetchTableData *scan);
+extern void heapam_index_fetch_end(IndexFetchTableData *scan);
+extern bool heapam_index_fetch_tuple(struct IndexFetchTableData *scan,
+ ItemPointer tid, Snapshot snapshot,
+ TupleTableSlot *slot, bool *heap_continue,
+ bool *all_dead);
+
/* in heap/pruneheap.c */
extern void heap_page_prune_opt(Relation relation, Buffer buffer,
Buffer *vmbuffer);
diff --git a/src/backend/access/heap/Makefile b/src/backend/access/heap/Makefile
index 394534172..1d27ccb91 100644
--- a/src/backend/access/heap/Makefile
+++ b/src/backend/access/heap/Makefile
@@ -15,6 +15,7 @@ include $(top_builddir)/src/Makefile.global
OBJS = \
heapam.o \
heapam_handler.o \
+ heapam_indexscan.o \
heapam_visibility.o \
heapam_xlog.o \
heaptoast.o \
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index d40878928..eff276f0d 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -75,115 +75,6 @@ heapam_slot_callbacks(Relation relation)
}
-/* ------------------------------------------------------------------------
- * Index Scan Callbacks for heap AM
- * ------------------------------------------------------------------------
- */
-
-static IndexFetchTableData *
-heapam_index_fetch_begin(Relation rel)
-{
- IndexFetchHeapData *hscan = palloc0_object(IndexFetchHeapData);
-
- hscan->xs_base.rel = rel;
- hscan->xs_cbuf = InvalidBuffer;
- hscan->xs_vmbuffer = InvalidBuffer;
-
- return &hscan->xs_base;
-}
-
-static void
-heapam_index_fetch_reset(IndexFetchTableData *scan)
-{
- IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan;
-
- if (BufferIsValid(hscan->xs_cbuf))
- {
- ReleaseBuffer(hscan->xs_cbuf);
- hscan->xs_cbuf = InvalidBuffer;
- }
-
- if (BufferIsValid(hscan->xs_vmbuffer))
- {
- ReleaseBuffer(hscan->xs_vmbuffer);
- hscan->xs_vmbuffer = InvalidBuffer;
- }
-}
-
-static void
-heapam_index_fetch_end(IndexFetchTableData *scan)
-{
- IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan;
-
- heapam_index_fetch_reset(scan);
-
- pfree(hscan);
-}
-
-static bool
-heapam_index_fetch_tuple(struct IndexFetchTableData *scan,
- ItemPointer tid,
- Snapshot snapshot,
- TupleTableSlot *slot,
- bool *call_again, bool *all_dead)
-{
- IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan;
- BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot;
- bool got_heap_tuple;
-
- Assert(TTS_IS_BUFFERTUPLE(slot));
-
- /* We can skip the buffer-switching logic if we're in mid-HOT chain. */
- if (!*call_again)
- {
- /* Switch to correct buffer if we don't have it already */
- Buffer prev_buf = hscan->xs_cbuf;
-
- hscan->xs_cbuf = ReleaseAndReadBuffer(hscan->xs_cbuf,
- hscan->xs_base.rel,
- ItemPointerGetBlockNumber(tid));
-
- /*
- * Prune page, but only if we weren't already on this page
- */
- if (prev_buf != hscan->xs_cbuf)
- heap_page_prune_opt(hscan->xs_base.rel, hscan->xs_cbuf,
- &hscan->xs_vmbuffer);
- }
-
- /* Obtain share-lock on the buffer so we can examine visibility */
- LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_SHARE);
- got_heap_tuple = heap_hot_search_buffer(tid,
- hscan->xs_base.rel,
- hscan->xs_cbuf,
- snapshot,
- &bslot->base.tupdata,
- all_dead,
- !*call_again);
- bslot->base.tupdata.t_self = *tid;
- LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_UNLOCK);
-
- if (got_heap_tuple)
- {
- /*
- * Only in a non-MVCC snapshot can more than one member of the HOT
- * chain be visible.
- */
- *call_again = !IsMVCCLikeSnapshot(snapshot);
-
- slot->tts_tableOid = RelationGetRelid(scan->rel);
- ExecStoreBufferHeapTuple(&bslot->base.tupdata, slot, hscan->xs_cbuf);
- }
- else
- {
- /* We've reached the end of the HOT chain. */
- *call_again = false;
- }
-
- return got_heap_tuple;
-}
-
-
/* ------------------------------------------------------------------------
* Callbacks for non-modifying operations on individual tuples for heap AM
* ------------------------------------------------------------------------
diff --git a/src/backend/access/heap/heapam_indexscan.c b/src/backend/access/heap/heapam_indexscan.c
new file mode 100644
index 000000000..4e8230834
--- /dev/null
+++ b/src/backend/access/heap/heapam_indexscan.c
@@ -0,0 +1,126 @@
+/*-------------------------------------------------------------------------
+ *
+ * heapam_indexscan.c
+ * heap table plain index scan and index-only scan code
+ *
+ * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/access/heap/heapam_indexscan.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "access/heapam.h"
+
+
+/* ------------------------------------------------------------------------
+ * Index Scan Callbacks for heap AM
+ * ------------------------------------------------------------------------
+ */
+
+IndexFetchTableData *
+heapam_index_fetch_begin(Relation rel)
+{
+ IndexFetchHeapData *hscan = palloc0_object(IndexFetchHeapData);
+
+ hscan->xs_base.rel = rel;
+ hscan->xs_cbuf = InvalidBuffer;
+ hscan->xs_vmbuffer = InvalidBuffer;
+
+ return &hscan->xs_base;
+}
+
+void
+heapam_index_fetch_reset(IndexFetchTableData *scan)
+{
+ IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan;
+
+ if (BufferIsValid(hscan->xs_cbuf))
+ {
+ ReleaseBuffer(hscan->xs_cbuf);
+ hscan->xs_cbuf = InvalidBuffer;
+ }
+
+ if (BufferIsValid(hscan->xs_vmbuffer))
+ {
+ ReleaseBuffer(hscan->xs_vmbuffer);
+ hscan->xs_vmbuffer = InvalidBuffer;
+ }
+}
+
+void
+heapam_index_fetch_end(IndexFetchTableData *scan)
+{
+ IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan;
+
+ heapam_index_fetch_reset(scan);
+
+ pfree(hscan);
+}
+
+bool
+heapam_index_fetch_tuple(struct IndexFetchTableData *scan,
+ ItemPointer tid,
+ Snapshot snapshot,
+ TupleTableSlot *slot,
+ bool *heap_continue, bool *all_dead)
+{
+ IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan;
+ BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot;
+ bool got_heap_tuple;
+
+ Assert(TTS_IS_BUFFERTUPLE(slot));
+
+ /* We can skip the buffer-switching logic if we're in mid-HOT chain. */
+ if (!*heap_continue)
+ {
+ /* Switch to correct buffer if we don't have it already */
+ Buffer prev_buf = hscan->xs_cbuf;
+
+ hscan->xs_cbuf = ReleaseAndReadBuffer(hscan->xs_cbuf,
+ hscan->xs_base.rel,
+ ItemPointerGetBlockNumber(tid));
+
+ /*
+ * Prune page, but only if we weren't already on this page
+ */
+ if (prev_buf != hscan->xs_cbuf)
+ heap_page_prune_opt(hscan->xs_base.rel, hscan->xs_cbuf,
+ &hscan->xs_vmbuffer);
+ }
+
+ /* Obtain share-lock on the buffer so we can examine visibility */
+ LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_SHARE);
+ got_heap_tuple = heap_hot_search_buffer(tid,
+ hscan->xs_base.rel,
+ hscan->xs_cbuf,
+ snapshot,
+ &bslot->base.tupdata,
+ all_dead,
+ !*heap_continue);
+ bslot->base.tupdata.t_self = *tid;
+ LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_UNLOCK);
+
+ if (got_heap_tuple)
+ {
+ /*
+ * Only in a non-MVCC snapshot can more than one member of the HOT
+ * chain be visible.
+ */
+ *heap_continue = !IsMVCCLikeSnapshot(snapshot);
+
+ slot->tts_tableOid = RelationGetRelid(scan->rel);
+ ExecStoreBufferHeapTuple(&bslot->base.tupdata, slot, hscan->xs_cbuf);
+ }
+ else
+ {
+ /* We've reached the end of the HOT chain. */
+ *heap_continue = false;
+ }
+
+ return got_heap_tuple;
+}
diff --git a/src/backend/access/heap/meson.build b/src/backend/access/heap/meson.build
index 92ab8be3d..00ec07d7f 100644
--- a/src/backend/access/heap/meson.build
+++ b/src/backend/access/heap/meson.build
@@ -3,6 +3,7 @@
backend_sources += files(
'heapam.c',
'heapam_handler.c',
+ 'heapam_indexscan.c',
'heapam_visibility.c',
'heapam_xlog.c',
'heaptoast.c',
--
2.53.0