| From: | Nikhil Kumar Veldanda <veldanda(dot)nikhilkumar17(at)gmail(dot)com> |
|---|---|
| To: | wenhui qiu <qiuwenhuifx(at)gmail(dot)com> |
| Cc: | Michael Paquier <michael(at)paquier(dot)xyz>, Postgres hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: ZSTD TOAST compression, and an extensible compression method encoding |
| Date: | 2026-09-25 21:42:11 |
| Message-ID: | CAFAfj_Ez1WnJojzcmN+CEBxVRbOE-ggyC6a9wMJzqUsj--SNkg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On Fri, Sep 25, 2026 at 5:35 AM wenhui qiu <qiuwenhuifx(at)gmail(dot)com> wrote:
>
> Hi Nikhil,
>
>
> Thanks for the updated patch set! Looking at patch 4/4, I noticed a minor issue in zstd_compress_datum() regarding the check for incompressible data:
>
> /* data is incompressible so just free the memory and return NULL */
> if (len > (size_t) valsize)
> {
> pfree(tmp);
> return NULL;
> }
> Should this condition be >= instead of >? if (len >= (size_t) valsize)
> Reasons:
> If len == valsize, the compressed payload alone is already the same size as the uncompressed data. Once VARHDRSZ_COMPRESSED_LONG (9 bytes) is added, the compressed datum is strictly larger than the original. There is no compression benefit here.
> If len == valsize, zstd_compress_datum() currently proceeds to call SET_VARSIZE_COMPRESSED() and returns tmp, only for the caller toast_compress_datum() to immediately reject it via if (VARSIZE(tmp) < valsize - 2) and pfree(tmp). Freeing it early and returning NULL saves redundant operations.
The check in the compressors is deliberately loose. The real decision
is made once for all methods in toast_compress_datum(), which knows
about the header and the alignment margin and rejects anything that
does not save more than 2 bytes with the header included. So for zstd
every result from len == valsize - 11 upwards is thrown away there.
Changing > to >= in the compressor catches one of those twelve
lengths; the other eleven still take the round trip. To actually
avoid it, each compressor would need a copy of the caller's threshold,
which is what keeping the policy in one place is meant to avoid.
The saving would also be one store and one comparison in a case that
does not happen in practice: zstd's frame overhead means
incompressible input comes out strictly longer than valsize.
> This is also consistent with lz4_compress_datum() in the same file:
>
> /*
> * If the compressed size is greater than or equal to the raw data size,
> * then data is incompressible so just free the memory and return NULL.
> */
> if (len >= valsize)
> {
> pfree(tmp);
> return NULL;
> }
lz4_compress_datum() in master has "if (len > valsize)", unchanged
since bbe0a81db69 added it. The zstd check is a copy of it, so the
two are consistent as they stand.
--
Nikhil Veldanda
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Melanie Plageman | 2026-09-25 21:54:01 | Hardening visibility-map maintenance and recovery |
| Previous Message | Matheus Alcantara | 2026-09-25 21:25:24 | Re: Several issues with postgres_fdw stats import |