| From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
|---|---|
| To: | Álvaro Herrera <alvherre(at)kurilemu(dot)de> |
| Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: heapam_relation_toast_am() returns the wrong AM for a wrapped heap AM |
| Date: | 2026-08-21 18:28:51 |
| Message-ID: | 20b9c059-d078-4086-a3b6-a9d180357e47@dunslane.net |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On 2026-08-21 Fr 12:50 PM, Álvaro Herrera wrote:
> On 2026-Aug-21, Andrew Dunstan wrote:
>
>> heapam_relation_toast_am() returns rel->rd_rel->relam instead of the
>> literal heap AM oid, on the assumption the two are always equal since
>> it's only meant to run for relations that are themselves heap. That
>> breaks for a table AM that copies heap's whole TableAmRoutine (via
>> GetHeapamTableAmRoutine()) and overrides only a few callbacks -- a
>> pattern heap_getnext()'s own identity check explicitly anticipates,
>> per its comment about allowing "regression tests that create another
>> AM reusing the heap handler." For such an AM, rel->rd_rel->relam is
>> its own oid, so NewRelationCreateToastTable() creates the TOAST table
>> with that AM too, and building its chunk_id/chunk_seq index then
>> fails in heap_getnext(), which requires rd_tableam to be literally
>> GetHeapamTableAmRoutine(): "only heap AM is supported" for any such
>> AM as soon as a table needs a TOAST table.
>>
>> Fix by returning the literal HEAP_TABLE_AM_OID, which is what the
>> function's own comment already claims it does ("TOAST tables for
>> heap relations are just heap relations").
> I'm not sure that this patch is correct. The heapam_relation_toast_am
> function is the implementation for the relation_toast_am callback in the
> heapam table AM. So this function is specific to heapam, and other
> table AMs should have their own if they want to have different behavior.
>
> The function is really small, so if a table AM that's not heapam can
> very easily set up its own callback function that returns
> HEAP_TABLE_AM_OID to get a regular heapam TOAST table, right?
>
> So "a table AM that [copies the whole heap TableAmRoutine and overrides
> only a handful of callbacks]" is Doing It Wrong by failing to also
> override relation_toast_am.
OK, fair enough, I withdraw the proposal. I guess the dummy AM I set up
for testing the AM options patch Did It Wrong ;-)
Maybe this hazard is worth documenting somewhere. I'll look for a good
place.
cheers
andrew
--
Andrew Dunstan
EDB: https://www.enterprisedb.com
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Matheus Alcantara | 2026-08-21 18:52:53 | Re: hashjoins vs. Bloom filters (yet again) |
| Previous Message | Andres Freund | 2026-08-21 18:21:25 | Re: heapam_relation_toast_am() returns the wrong AM for a wrapped heap AM |