create type infomask_bit_desc as (mask varbit, symbol text); create or replace function infomask(msk int, which int) returns text language plpgsql as $$ declare r infomask_bit_desc; str text = ''; append_bar bool = false; begin for r in select * from infomask_bits(which) loop if (msk::bit(16) & r.mask)::int <> 0 then if append_bar then str = str || '|'; end if; append_bar = true; str = str || r.symbol; end if; end loop; return str; end; $$ ; create or replace function infomask_bits(which int) returns setof infomask_bit_desc language plpgsql as $$ begin if which = 1 then return query values (x'8000'::varbit, 'MOVED_IN'), (x'4000', 'MOVED_OFF'), (x'2000', 'UPDATED'), (x'1000', 'XMAX_IS_MULTI'), (x'0800', 'XMAX_INVALID'), (x'0400', 'XMAX_COMMITTED'), (x'0200', 'XMIN_INVALID'), (x'0100', 'XMIN_COMMITTED'), (x'0080', 'XMAX_LOCK_ONLY'), (x'0040', 'EXCL_LOCK'), (x'0020', 'COMBOCID'), (x'0010', 'XMAX_KEYSHR_LOCK'), (x'0008', 'HASOID'), (x'0004', 'HASEXTERNAL'), (x'0002', 'HASVARWIDTH'), (x'0001', 'HASNULL'); elsif which = 2 then return query values (x'2000'::varbit, 'UPDATE_KEY_REVOKED'), (x'4000', 'HOT_UPDATED'), (x'8000', 'HEAP_ONLY_TUPLE'); end if; end; $$; create extension if not exists pageinspect;