postgresql/src/test/regress/sql/indirect_toast.sql
Robert Haas 3682025015 Add support for multiple kinds of external toast datums.
To that end, support tags rather than lengths for external datums.
As an example of how this can be used, add support or "indirect"
tuples which point to some externally allocated memory containing
a toast tuple.  Similar infrastructure could be used for other
purposes, including, perhaps, support for alternative compression
algorithms.

Andres Freund, reviewed by Hitoshi Harada and myself
2013-07-02 13:38:55 -04:00

61 lines
2.6 KiB
PL/PgSQL

CREATE TABLE toasttest(descr text, cnt int DEFAULT 0, f1 text, f2 text);
INSERT INTO toasttest(descr, f1, f2) VALUES('two-compressed', repeat('1234567890',1000), repeat('1234567890',1000));
INSERT INTO toasttest(descr, f1, f2) VALUES('two-toasted', repeat('1234567890',30000), repeat('1234567890',50000));
INSERT INTO toasttest(descr, f1, f2) VALUES('one-compressed,one-null', NULL, repeat('1234567890',1000));
INSERT INTO toasttest(descr, f1, f2) VALUES('one-toasted,one-null', NULL, repeat('1234567890',50000));
-- check whether indirect tuples works on the most basic level
SELECT descr, substring(make_tuple_indirect(toasttest)::text, 1, 200) FROM toasttest;
-- modification without changing varlenas
UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
-- modification without modifying asigned value
UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text, 1, 200);
-- modification modifying, but effectively not changing
UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::text, 1, 200);
UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toasttest::text, 1, 200);
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
-- check we didn't screw with main/toast tuple visiblity
VACUUM FREEZE toasttest;
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
-- now create a trigger that forces all Datums to be indirect ones
CREATE FUNCTION update_using_indirect()
RETURNS trigger
LANGUAGE plpgsql AS $$
BEGIN
NEW := make_tuple_indirect(NEW);
RETURN NEW;
END$$;
CREATE TRIGGER toasttest_update_indirect
BEFORE INSERT OR UPDATE
ON toasttest
FOR EACH ROW
EXECUTE PROCEDURE update_using_indirect();
-- modification without changing varlenas
UPDATE toasttest SET cnt = cnt +1 RETURNING substring(toasttest::text, 1, 200);
-- modification without modifying asigned value
UPDATE toasttest SET cnt = cnt +1, f1 = f1 RETURNING substring(toasttest::text, 1, 200);
-- modification modifying, but effectively not changing
UPDATE toasttest SET cnt = cnt +1, f1 = f1||'' RETURNING substring(toasttest::text, 1, 200);
UPDATE toasttest SET cnt = cnt +1, f1 = '-'||f1||'-' RETURNING substring(toasttest::text, 1, 200);
INSERT INTO toasttest(descr, f1, f2) VALUES('one-toasted,one-null, via indirect', repeat('1234567890',30000), NULL);
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
-- check we didn't screw with main/toast tuple visiblity
VACUUM FREEZE toasttest;
SELECT substring(toasttest::text, 1, 200) FROM toasttest;
DROP TABLE toasttest;
DROP FUNCTION update_using_indirect();