tid_blockno() and tid_offset() accessor functions

From: Ayush Tiwari <ayushtiwari(dot)slg01(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: tid_blockno() and tid_offset() accessor functions
Date: 2026-02-27 18:59:20
Message-ID: CAJTYsWUzok2+mvSYkbVUwq_SWWg-GdHqCuYumN82AU97SjwjCA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi hackers,

As of now we don't have any built-in way to extract the block and offset
components from a TID. When people need to group by page (like for bloat
analysis) or filter by specific blocks, they usually end up using the
`ctid::text::point` hack:

SELECT (ctid::text::point)[0]::bigint AS blockno,
(ctid::text::point)[1]::int AS offset
FROM my_table;

This works, but it's pretty clunky, relies on the text representation, and
isn't great if you're trying to parse TIDs outside of SQL.

The attached patch adds two simple accessor functions:
- `tid_blockno(tid) -> bigint`
- `tid_offset(tid) -> integer`

A couple of quick notes on the implementation I went for:
- `tid_blockno` returns `int8` since `BlockNumber` is `uint32` and could
overflow `int4`.
- `tid_offset` returns `int4` since `OffsetNumber` is `uint16`.
- Both are marked leakproof and strict.
- I used the `NoCheck` macros from `itemptr.h` so they safely handle
user-supplied literals like `(0,0)`.

Please let me know what you think!

Regards,
Ayush

Attachment Content-Type Size
0001-Add-tid_blockno-and-tid_offset-accessor-functions.patch application/octet-stream 7.8 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message 陈宗志 2026-02-27 19:11:01 Re: [PROPOSAL] Doublewrite Buffer as an alternative torn page protection to Full Page Write
Previous Message Dmitry Dolgov 2026-02-27 18:57:00 Re: Add ssl_(supported|shared)_groups to sslinfo