1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-03 22:24:49 +03:00

Add and use BitmapHeapScanDescData struct

Move the several members of HeapScanDescData which are specific to
Bitmap Heap Scans into a new struct, BitmapHeapScanDescData, which
inherits from HeapScanDescData.

This reduces the size of the HeapScanDescData for other types of scans
and will allow us to add additional bitmap heap scan-specific members in
the future without fear of bloating the HeapScanDescData.

Reviewed-by: Tomas Vondra
Discussion: https://postgr.es/m/c736f6aa-8b35-4e20-9621-62c7c82e2168%40vondra.me
This commit is contained in:
Melanie Plageman 2025-01-16 18:42:39 -05:00
parent 7b6468cc95
commit f7a8fc10cc
4 changed files with 63 additions and 32 deletions

View File

@ -1048,7 +1048,16 @@ heap_beginscan(Relation relation, Snapshot snapshot,
/* /*
* allocate and initialize scan descriptor * allocate and initialize scan descriptor
*/ */
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData)); if (flags & SO_TYPE_BITMAPSCAN)
{
BitmapHeapScanDesc bscan = palloc(sizeof(BitmapHeapScanDescData));
bscan->rs_vmbuffer = InvalidBuffer;
bscan->rs_empty_tuples_pending = 0;
scan = (HeapScanDesc) bscan;
}
else
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
scan->rs_base.rs_rd = relation; scan->rs_base.rs_rd = relation;
scan->rs_base.rs_snapshot = snapshot; scan->rs_base.rs_snapshot = snapshot;
@ -1056,8 +1065,6 @@ heap_beginscan(Relation relation, Snapshot snapshot,
scan->rs_base.rs_flags = flags; scan->rs_base.rs_flags = flags;
scan->rs_base.rs_parallel = parallel_scan; scan->rs_base.rs_parallel = parallel_scan;
scan->rs_strategy = NULL; /* set in initscan */ scan->rs_strategy = NULL; /* set in initscan */
scan->rs_vmbuffer = InvalidBuffer;
scan->rs_empty_tuples_pending = 0;
/* /*
* Disable page-at-a-time mode if it's not a MVCC-safe snapshot. * Disable page-at-a-time mode if it's not a MVCC-safe snapshot.
@ -1173,18 +1180,23 @@ heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
if (BufferIsValid(scan->rs_cbuf)) if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf); ReleaseBuffer(scan->rs_cbuf);
if (BufferIsValid(scan->rs_vmbuffer)) if (scan->rs_base.rs_flags & SO_TYPE_BITMAPSCAN)
{ {
ReleaseBuffer(scan->rs_vmbuffer); BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
scan->rs_vmbuffer = InvalidBuffer;
}
/* /*
* Reset rs_empty_tuples_pending, a field only used by bitmap heap scan, * Reset empty_tuples_pending, a field only used by bitmap heap scan,
* to avoid incorrectly emitting NULL-filled tuples from a previous scan * to avoid incorrectly emitting NULL-filled tuples from a previous
* on rescan. * scan on rescan.
*/ */
scan->rs_empty_tuples_pending = 0; bscan->rs_empty_tuples_pending = 0;
if (BufferIsValid(bscan->rs_vmbuffer))
{
ReleaseBuffer(bscan->rs_vmbuffer);
bscan->rs_vmbuffer = InvalidBuffer;
}
}
/* /*
* The read stream is reset on rescan. This must be done before * The read stream is reset on rescan. This must be done before
@ -1213,8 +1225,14 @@ heap_endscan(TableScanDesc sscan)
if (BufferIsValid(scan->rs_cbuf)) if (BufferIsValid(scan->rs_cbuf))
ReleaseBuffer(scan->rs_cbuf); ReleaseBuffer(scan->rs_cbuf);
if (BufferIsValid(scan->rs_vmbuffer)) if (scan->rs_base.rs_flags & SO_TYPE_BITMAPSCAN)
ReleaseBuffer(scan->rs_vmbuffer); {
BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) sscan;
bscan->rs_empty_tuples_pending = 0;
if (BufferIsValid(bscan->rs_vmbuffer))
ReleaseBuffer(bscan->rs_vmbuffer);
}
/* /*
* Must free the read stream before freeing the BufferAccessStrategy. * Must free the read stream before freeing the BufferAccessStrategy.

View File

@ -2118,13 +2118,16 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
BlockNumber *blockno, bool *recheck, BlockNumber *blockno, bool *recheck,
uint64 *lossy_pages, uint64 *exact_pages) uint64 *lossy_pages, uint64 *exact_pages)
{ {
HeapScanDesc hscan = (HeapScanDesc) scan; BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
HeapScanDesc hscan = (HeapScanDesc) bscan;
BlockNumber block; BlockNumber block;
Buffer buffer; Buffer buffer;
Snapshot snapshot; Snapshot snapshot;
int ntup; int ntup;
TBMIterateResult *tbmres; TBMIterateResult *tbmres;
Assert(scan->rs_flags & SO_TYPE_BITMAPSCAN);
hscan->rs_cindex = 0; hscan->rs_cindex = 0;
hscan->rs_ntuples = 0; hscan->rs_ntuples = 0;
@ -2162,13 +2165,13 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
*/ */
if (!(scan->rs_flags & SO_NEED_TUPLES) && if (!(scan->rs_flags & SO_NEED_TUPLES) &&
!tbmres->recheck && !tbmres->recheck &&
VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &hscan->rs_vmbuffer)) VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &bscan->rs_vmbuffer))
{ {
/* can't be lossy in the skip_fetch case */ /* can't be lossy in the skip_fetch case */
Assert(tbmres->ntuples >= 0); Assert(tbmres->ntuples >= 0);
Assert(hscan->rs_empty_tuples_pending >= 0); Assert(bscan->rs_empty_tuples_pending >= 0);
hscan->rs_empty_tuples_pending += tbmres->ntuples; bscan->rs_empty_tuples_pending += tbmres->ntuples;
return true; return true;
} }
@ -2282,18 +2285,19 @@ static bool
heapam_scan_bitmap_next_tuple(TableScanDesc scan, heapam_scan_bitmap_next_tuple(TableScanDesc scan,
TupleTableSlot *slot) TupleTableSlot *slot)
{ {
HeapScanDesc hscan = (HeapScanDesc) scan; BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
HeapScanDesc hscan = (HeapScanDesc) bscan;
OffsetNumber targoffset; OffsetNumber targoffset;
Page page; Page page;
ItemId lp; ItemId lp;
if (hscan->rs_empty_tuples_pending > 0) if (bscan->rs_empty_tuples_pending > 0)
{ {
/* /*
* If we don't have to fetch the tuple, just return nulls. * If we don't have to fetch the tuple, just return nulls.
*/ */
ExecStoreAllNullTuple(slot); ExecStoreAllNullTuple(slot);
hscan->rs_empty_tuples_pending--; bscan->rs_empty_tuples_pending--;
return true; return true;
} }

View File

@ -92,16 +92,6 @@ typedef struct HeapScanDescData
*/ */
ParallelBlockTableScanWorkerData *rs_parallelworkerdata; ParallelBlockTableScanWorkerData *rs_parallelworkerdata;
/*
* These fields are only used for bitmap scans for the "skip fetch"
* optimization. Bitmap scans needing no fields from the heap may skip
* fetching an all visible block, instead using the number of tuples per
* block reported by the bitmap to determine how many NULL-filled tuples
* to return.
*/
Buffer rs_vmbuffer;
int rs_empty_tuples_pending;
/* these fields only used in page-at-a-time mode and for bitmap scans */ /* these fields only used in page-at-a-time mode and for bitmap scans */
uint32 rs_cindex; /* current tuple's index in vistuples */ uint32 rs_cindex; /* current tuple's index in vistuples */
uint32 rs_ntuples; /* number of visible tuples on page */ uint32 rs_ntuples; /* number of visible tuples on page */
@ -109,6 +99,24 @@ typedef struct HeapScanDescData
} HeapScanDescData; } HeapScanDescData;
typedef struct HeapScanDescData *HeapScanDesc; typedef struct HeapScanDescData *HeapScanDesc;
typedef struct BitmapHeapScanDescData
{
HeapScanDescData rs_heap_base;
/*
* These fields are only used for bitmap scans for the "skip fetch"
* optimization. Bitmap scans needing no fields from the heap may skip
* fetching an all visible block, instead using the number of tuples per
* block reported by the bitmap to determine how many NULL-filled tuples
* to return. They are common to parallel and serial BitmapHeapScans
*/
/* page of VM containing info for current block */
Buffer rs_vmbuffer;
int rs_empty_tuples_pending;
} BitmapHeapScanDescData;
typedef struct BitmapHeapScanDescData *BitmapHeapScanDesc;
/* /*
* Descriptor for fetches from heap via an index. * Descriptor for fetches from heap via an index.
*/ */

View File

@ -264,6 +264,7 @@ BitmapAndState
BitmapHeapPath BitmapHeapPath
BitmapHeapScan BitmapHeapScan
BitmapHeapScanInstrumentation BitmapHeapScanInstrumentation
BitmapHeapScanDesc
BitmapHeapScanState BitmapHeapScanState
BitmapIndexScan BitmapIndexScan
BitmapIndexScanState BitmapIndexScanState