Skip to content

Commit 69f75d6

Browse files
committed
Add SQL test for TOAST value allocations on rewrite
The SQL test added in this commit check a specific code path that had no coverage until now. When a TOAST datum is rewritten, toast_save_datum() has a dedicated path to make sure that a new value is allocated if it does not exist on the TOAST table yet. This test uses a trick with PLAIN and EXTERNAL storage, with a tuple large enough to be toasted and small enough to fit on a page. It is initially stored in plain more, and the rewrite forces the tuple to be stored externally. The key point is that there is no value allocated during the initial insert, and that there is one after the rewrite. A second pattern checked is the reuse of the same value across rewrites, using \gset. A set of patches under discussion is messing up with this area of the code, so this makes sure that such rewrite cases remain consistent across the board. Author: Nikhil Kumar Veldanda <veldanda.nikhilkumar17@gmail.com> Co-authored-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CAFAfj_E+kw5P713S8_jZyVgQAGVFfzFiTUJPrgo-TTtJJoazQw@mail.gmail.com
1 parent 60b64e6 commit 69f75d6

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/test/regress/expected/vacuum.out

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,49 @@ RESET ROLE;
686686
DROP TABLE vacowned;
687687
DROP TABLE vacowned_parted;
688688
DROP ROLE regress_vacuum;
689+
-- Test checking how new toast values are allocated on rewrite.
690+
-- Create table with plain storage (forces inline storage initially).
691+
CREATE TABLE vac_rewrite_toast (id int, f1 TEXT STORAGE plain);
692+
-- Insert tuple large enough to trigger toast storage on rewrite, still
693+
-- small enough to fit on a page.
694+
INSERT INTO vac_rewrite_toast values (1, repeat('a', 7000));
695+
-- Switch to external storage to force toast table usage.
696+
ALTER TABLE vac_rewrite_toast ALTER COLUMN f1 SET STORAGE EXTERNAL;
697+
-- This second tuple is toasted, its value should still be the
698+
-- same after rewrite.
699+
INSERT INTO vac_rewrite_toast values (2, repeat('a', 7000));
700+
SELECT pg_column_toast_chunk_id(f1) AS id_2_chunk FROM vac_rewrite_toast
701+
WHERE id = 2 \gset
702+
-- Check initial state of the data.
703+
SELECT id, pg_column_toast_chunk_id(f1) IS NULL AS f1_chunk_null,
704+
substr(f1, 5, 10) AS f1_data,
705+
pg_column_compression(f1) AS f1_comp
706+
FROM vac_rewrite_toast ORDER BY id;
707+
id | f1_chunk_null | f1_data | f1_comp
708+
----+---------------+------------+---------
709+
1 | t | aaaaaaaaaa |
710+
2 | f | aaaaaaaaaa |
711+
(2 rows)
712+
713+
-- VACUUM FULL forces toast data rewrite.
714+
VACUUM FULL vac_rewrite_toast;
715+
-- Check after rewrite.
716+
SELECT id, pg_column_toast_chunk_id(f1) IS NULL AS f1_chunk_null,
717+
substr(f1, 5, 10) AS f1_data,
718+
pg_column_compression(f1) AS f1_comp
719+
FROM vac_rewrite_toast ORDER BY id;
720+
id | f1_chunk_null | f1_data | f1_comp
721+
----+---------------+------------+---------
722+
1 | f | aaaaaaaaaa |
723+
2 | f | aaaaaaaaaa |
724+
(2 rows)
725+
726+
-- The same value is reused for the tuple toasted before the rewrite.
727+
SELECT pg_column_toast_chunk_id(f1) = :'id_2_chunk' AS same_chunk
728+
FROM vac_rewrite_toast WHERE id = 2;
729+
same_chunk
730+
------------
731+
t
732+
(1 row)
733+
734+
DROP TABLE vac_rewrite_toast;

src/test/regress/sql/vacuum.sql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,33 @@ RESET ROLE;
495495
DROP TABLE vacowned;
496496
DROP TABLE vacowned_parted;
497497
DROP ROLE regress_vacuum;
498+
499+
-- Test checking how new toast values are allocated on rewrite.
500+
-- Create table with plain storage (forces inline storage initially).
501+
CREATE TABLE vac_rewrite_toast (id int, f1 TEXT STORAGE plain);
502+
-- Insert tuple large enough to trigger toast storage on rewrite, still
503+
-- small enough to fit on a page.
504+
INSERT INTO vac_rewrite_toast values (1, repeat('a', 7000));
505+
-- Switch to external storage to force toast table usage.
506+
ALTER TABLE vac_rewrite_toast ALTER COLUMN f1 SET STORAGE EXTERNAL;
507+
-- This second tuple is toasted, its value should still be the
508+
-- same after rewrite.
509+
INSERT INTO vac_rewrite_toast values (2, repeat('a', 7000));
510+
SELECT pg_column_toast_chunk_id(f1) AS id_2_chunk FROM vac_rewrite_toast
511+
WHERE id = 2 \gset
512+
-- Check initial state of the data.
513+
SELECT id, pg_column_toast_chunk_id(f1) IS NULL AS f1_chunk_null,
514+
substr(f1, 5, 10) AS f1_data,
515+
pg_column_compression(f1) AS f1_comp
516+
FROM vac_rewrite_toast ORDER BY id;
517+
-- VACUUM FULL forces toast data rewrite.
518+
VACUUM FULL vac_rewrite_toast;
519+
-- Check after rewrite.
520+
SELECT id, pg_column_toast_chunk_id(f1) IS NULL AS f1_chunk_null,
521+
substr(f1, 5, 10) AS f1_data,
522+
pg_column_compression(f1) AS f1_comp
523+
FROM vac_rewrite_toast ORDER BY id;
524+
-- The same value is reused for the tuple toasted before the rewrite.
525+
SELECT pg_column_toast_chunk_id(f1) = :'id_2_chunk' AS same_chunk
526+
FROM vac_rewrite_toast WHERE id = 2;
527+
DROP TABLE vac_rewrite_toast;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy