postgresql/src/test/regress/sql/compression_pglz.sql
Michael Paquier caee654e05 Add tests for low-level PGLZ [de]compression routines
The goal of this module is to provide an entry point for the coverage of
the low-level compression and decompression PGLZ routines.  The new test
is moved to a new parallel group, with all the existing
compression-related tests added to it.

This includes tests for the cases detected by fuzzing that emulate
corrupted compressed data, as fixed by 2b5ba2a0a1:
- Set control bit with read of a match tag, where no data follows.
- Set control bit with read of a match tag, where 1 byte follows.
- Set control bit with match tag where length nibble is 3 bytes
(extended case).

While on it, some tests are added for compress/decompress roundtrips,
and for check_complete=false/true.  Like 2b5ba2a0a1, backpatch to all
the stable branches.

Discussion: https://postgr.es/m/adw647wuGjh1oU6p@paquier.xyz
Backpatch-through: 14
2026-04-15 05:09:12 +09:00

53 lines
1.9 KiB
SQL

--
-- Tests for PGLZ compression
--
-- directory paths and dlsuffix are passed to us in environment variables
\getenv libdir PG_LIBDIR
\getenv dlsuffix PG_DLSUFFIX
\set regresslib :libdir '/regress' :dlsuffix
CREATE FUNCTION test_pglz_compress(bytea)
RETURNS bytea
AS :'regresslib' LANGUAGE C STRICT;
CREATE FUNCTION test_pglz_decompress(bytea, int4, bool)
RETURNS bytea
AS :'regresslib' LANGUAGE C STRICT;
-- Round-trip with pglz: compress then decompress.
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 400, false) =
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok;
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 400, true) =
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok;
-- Decompression with rawsize too large, fails to fill the destination
-- buffer.
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 500, true);
-- Decompression with rawsize too small, fails with source not fully
-- consumed.
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 100, true);
-- Corrupted compressed data. Set control bit with read of a match tag,
-- no data follows.
SELECT length(test_pglz_decompress('\x01'::bytea, 1024, false)) AS ctrl_only_len;
SELECT test_pglz_decompress('\x01'::bytea, 1024, true);
-- Corrupted compressed data. Set control bit with read of a match tag,
-- 1 byte follows.
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, false);
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, true);
-- Corrupted compressed data. Set control bit with match tag where length
-- nibble is 3 bytes (extended length), no data follows.
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, false);
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, true);
-- Clean up
DROP FUNCTION test_pglz_compress;
DROP FUNCTION test_pglz_decompress;