Fix brin_form_tuple to properly detoast data

Tomas Vondra <tomas.vondra@2ndquadrant.com>

From: Tomas Vondra <tomas.vondra@2ndquadrant.com>
To: pgsql-hackers@postgresql.org
Date: 2020-11-04T01:05:44Z
Lists: pgsql-hackers

Attachments

Hi,

As pointed out in [1], BRIN is not properly handling toasted data, which
may easily lead to index tuples referencing TOAST-ed values. Which is
clearly wrong - it's trivial to trigger failues after a DELETE.

Attached is a patch that aims to fix this - AFAIK the brin_form_tuple
was simply missing the TOAST_INDEX_HACK stuff from index_form_tuple,
which ensures the data is detoasted and (possibly) re-compressed. The
code is mostly the same, with some BRIN-specific tweaks (looking at
oi_typecache instead of the index descriptor, etc.).

I also attach a simple SQL script that I used to trigger the issue. This
needs to be turned into a regression test, I'll work on that tomorrow.


A separate question is what to do about existing indexes - ISTM the only
thing we can do is to tell the users to reindex all BRIN indexes on
varlena values. Something like this:

     select * from pg_class
      where relam = (select oid from pg_am where amname = 'brin')
        and oid in (select attrelid from pg_attribute where attlen = -1
                                     and attstorage in ('e', 'x'));


regards


[1] https://www.postgresql.org/message-id/20201001184133.oq5uq75sb45pu3aw%40development

-- 
Tomas Vondra                  http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services 

Commits

  1. Properly detoast data in brin_form_tuple

  2. Centralize horizon determination for temp tables, fixing bug due to skew.