blob: 498ed48d4ebe16d8d3c5d8483fd0f9b68cc222ff [file] [log] [blame]
CREATE TABLE motiondata (
id int,
plain text, -- inline, uncompressed
main text, --inline, compressible
external text, -- external, uncompressed
extended text); -- external, compressible
ALTER TABLE motiondata ALTER COLUMN plain SET STORAGE plain;
ALTER TABLE motiondata ALTER COLUMN main SET STORAGE main;
ALTER TABLE motiondata ALTER COLUMN external SET STORAGE external;
ALTER TABLE motiondata ALTER COLUMN extended SET STORAGE extended;
-- a simple small tuple.
INSERT INTO motiondata (id, plain, main, external, extended) VALUES (1, 'foo', 'bar', 'baz', 'foobar');
-- Large datum, inline uncompressed
INSERT INTO motiondata (id, plain) VALUES (2, repeat('1234567890', 1000));
-- Large datum, inline compressed
INSERT INTO motiondata (id, main) VALUES (3, repeat('1234567890', 1000));
-- Large datum, inline compressed, but doesn't fit in a short varlen even
-- after compression
INSERT INTO motiondata (id, main) VALUES (4, repeat('1234567890', 2000));
-- Large datum, external uncompressed
INSERT INTO motiondata (id, external) VALUES (5, repeat('1234567890', 1000));
-- Large datum, external, compressed
INSERT INTO motiondata (id, extended) VALUES (6, repeat('1234567890', 100000));
-- Check that the sizes are as expected. The exact sizes are not important,
-- but should be in the right ballpark.
SELECT id,
pg_column_size(plain) AS plain_sz,
pg_column_size(main) AS main_sz,
pg_column_size(external) AS external_sz,
pg_column_size(extended) AS extended_sz
FROM motiondata;
CREATE TABLE motiondata_ao WITH (appendonly=true) AS SELECT * from motiondata;
-- A helper function for printing an abbreviated version of a long datum. Otherwise, the output
-- of selecting the large datums become unwieldly.
create or replace function abbreviate(t text) returns text as $$
begin
if length(t) <= 15 then
return length(t) || ': ' || t;
else
return length(t) || ': ' || substring(t from 1 for 5) || '...' || substring(t from length(t)-4 for 5);
end if;
end;
$$ language plpgsql;
-- Runs query 'sql', and prints an abbreviated result set.
--
-- Note: It's important that we run the query as it is, and abbreviate the
-- resulting values afterwards. If we put the abbreviate() function calls into
-- the query itself, then they will be evaluated in the QEs, and the original
-- large datums are not sent through the Motion at all. Since we're trying to
-- test the Motion tuple serialization code, that would defeat the purpose.
create or replace function abbreviate_result(sql text) returns setof motiondata
as $$
declare
rec motiondata%rowtype;
begin
for rec in EXECUTE sql
loop
rec.plain = abbreviate(rec.plain);
rec.main = abbreviate(rec.main);
rec.external = abbreviate(rec.external);
rec.extended = abbreviate(rec.extended);
RETURN NEXT rec ;
end loop;
end;
$$ language plpgsql;
-- This exercises the codepath where the HeapTuple is sent over the wire as is, if it
-- doesn't contain toasted datums.
select * from abbreviate_result($$
select id, plain, main, external, extended from motiondata
$$) order by id;
-- Because of the 'id + 0' expression, the Seq Scan node has to project,
-- and passes a virtual slot to the Motion.
select * from abbreviate_result($$
select id + 0 as id, plain, main, external, extended from motiondata
$$) order by id;
-- Here, the Motion gets an already-built MemTuple from the Seq Scan, because it's
-- an AO table.
select * from abbreviate_result($$
select id, plain, main, external, extended from motiondata_ao
$$) order by id;
-- Test with a table with zero columns. Motion tuple serialization has a special
-- codepath for zero-attribute tuples.
CREATE TABLE motion_noatts ();
INSERT INTO motion_noatts SELECT;
SELECT * FROM motion_noatts;