Perform-ScanKey-evaluation-in-slot-form.patch
application/octet-stream
Filename: Perform-ScanKey-evaluation-in-slot-form.patch
Type: application/octet-stream
Part: 0
Message:
Re: Qual push down to table AM
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1
Subject: Perform ScanKey evaluation in slot form
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam.c | 20 | 13 |
| src/include/access/valid.h | 7 | 2 |
From 9035f48eb107e454012e37fa62d67cee6d1d5f8f Mon Sep 17 00:00:00 2001
From: Maxime Schoemans <maxime.schoemans@enterprisedb.com>
Date: Thu, 18 Dec 2025 15:34:26 +0100
Subject: [PATCH v1] Perform ScanKey evaluation in slot form
---
src/backend/access/heap/heapam.c | 33 +++++++++++++++++++-------------
src/include/access/valid.h | 9 +++++++--
2 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 6daf4a87dec..97fc583d8c4 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -31,6 +31,7 @@
*/
#include "postgres.h"
+#include "access/genam.h"
#include "access/heapam.h"
#include "access/heaptoast.h"
#include "access/hio.h"
@@ -43,6 +44,7 @@
#include "catalog/pg_database.h"
#include "catalog/pg_database_d.h"
#include "commands/vacuum.h"
+#include "executor/tuptable.h"
#include "pgstat.h"
#include "port/pg_bitutils.h"
#include "storage/lmgr.h"
@@ -911,7 +913,8 @@ static void
heapgettup(HeapScanDesc scan,
ScanDirection dir,
int nkeys,
- ScanKey key)
+ ScanKey key,
+ TupleTableSlot *slot)
{
HeapTuple tuple = &(scan->rs_ctup);
Page page;
@@ -975,10 +978,13 @@ continue_page:
if (!visible)
continue;
+ if (slot)
+ ExecStoreBufferHeapTuple(&scan->rs_ctup, slot, scan->rs_cbuf);
+
/* skip any tuples that don't match the scan key */
if (key != NULL &&
!HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd),
- nkeys, key))
+ nkeys, key, slot))
continue;
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
@@ -1021,7 +1027,8 @@ static void
heapgettup_pagemode(HeapScanDesc scan,
ScanDirection dir,
int nkeys,
- ScanKey key)
+ ScanKey key,
+ TupleTableSlot *slot)
{
HeapTuple tuple = &(scan->rs_ctup);
Page page;
@@ -1083,10 +1090,13 @@ continue_page:
tuple->t_len = ItemIdGetLength(lpp);
ItemPointerSetOffsetNumber(&tuple->t_self, lineoff);
+ if (slot)
+ ExecStoreBufferHeapTuple(&scan->rs_ctup, slot, scan->rs_cbuf);
+
/* skip any tuples that don't match the scan key */
if (key != NULL &&
!HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd),
- nkeys, key))
+ nkeys, key, slot))
continue;
scan->rs_cindex = lineindex;
@@ -1388,10 +1398,10 @@ heap_getnext(TableScanDesc sscan, ScanDirection direction)
if (scan->rs_base.rs_flags & SO_ALLOW_PAGEMODE)
heapgettup_pagemode(scan, direction,
- scan->rs_base.rs_nkeys, scan->rs_base.rs_key);
+ scan->rs_base.rs_nkeys, scan->rs_base.rs_key, NULL);
else
heapgettup(scan, direction,
- scan->rs_base.rs_nkeys, scan->rs_base.rs_key);
+ scan->rs_base.rs_nkeys, scan->rs_base.rs_key, NULL);
if (scan->rs_ctup.t_data == NULL)
return NULL;
@@ -1414,9 +1424,9 @@ heap_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *s
/* Note: no locking manipulations needed */
if (sscan->rs_flags & SO_ALLOW_PAGEMODE)
- heapgettup_pagemode(scan, direction, sscan->rs_nkeys, sscan->rs_key);
+ heapgettup_pagemode(scan, direction, sscan->rs_nkeys, sscan->rs_key, slot);
else
- heapgettup(scan, direction, sscan->rs_nkeys, sscan->rs_key);
+ heapgettup(scan, direction, sscan->rs_nkeys, sscan->rs_key, slot);
if (scan->rs_ctup.t_data == NULL)
{
@@ -1431,8 +1441,6 @@ heap_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *s
pgstat_count_heap_getnext(scan->rs_base.rs_rd);
- ExecStoreBufferHeapTuple(&scan->rs_ctup, slot,
- scan->rs_cbuf);
return true;
}
@@ -1521,9 +1529,9 @@ heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction,
for (;;)
{
if (sscan->rs_flags & SO_ALLOW_PAGEMODE)
- heapgettup_pagemode(scan, direction, sscan->rs_nkeys, sscan->rs_key);
+ heapgettup_pagemode(scan, direction, sscan->rs_nkeys, sscan->rs_key, slot);
else
- heapgettup(scan, direction, sscan->rs_nkeys, sscan->rs_key);
+ heapgettup(scan, direction, sscan->rs_nkeys, sscan->rs_key, slot);
if (scan->rs_ctup.t_data == NULL)
{
@@ -1579,7 +1587,6 @@ heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction,
*/
pgstat_count_heap_getnext(scan->rs_base.rs_rd);
- ExecStoreBufferHeapTuple(&scan->rs_ctup, slot, scan->rs_cbuf);
return true;
}
diff --git a/src/include/access/valid.h b/src/include/access/valid.h
index 8b33089dac4..2f272294784 100644
--- a/src/include/access/valid.h
+++ b/src/include/access/valid.h
@@ -18,6 +18,7 @@
#include "access/htup_details.h"
#include "access/skey.h"
#include "access/tupdesc.h"
+#include "executor/tuptable.h"
/*
* HeapKeyTest
@@ -25,7 +26,8 @@
* Test a heap tuple to see if it satisfies a scan key.
*/
static inline bool
-HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys)
+HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys,
+ TupleTableSlot *slot)
{
int cur_nkeys = nkeys;
ScanKey cur_key = keys;
@@ -39,7 +41,10 @@ HeapKeyTest(HeapTuple tuple, TupleDesc tupdesc, int nkeys, ScanKey keys)
if (cur_key->sk_flags & SK_ISNULL)
return false;
- atp = heap_getattr(tuple, cur_key->sk_attno, tupdesc, &isnull);
+ if (slot)
+ atp = slot_getattr(slot, cur_key->sk_attno, &isnull);
+ else
+ atp = heap_getattr(tuple, cur_key->sk_attno, tupdesc, &isnull);
if (isnull)
return false;
--
2.50.1 (Apple Git-155)