-- sarov bench 0.2
-- Emulate nested functions calls with exceptions handling. Each exception block
-- internally will be transformed into a savepoint. Also do some inserts to generate
-- xid and select for share to generate some contention on pg_multixact.
create or replace function such_much_safe_function(depth int, scale int) returns void as $$
    declare
        xaid int = (random()*100000*scale)::int;
        acc pgbench_accounts;
    begin
        if (depth > 0) then
            select * from pgbench_accounts where aid = xaid for share into acc;
            perform such_much_safe_function(depth - 1);
        end if;
    exception when others then RAISE NOTICE '% %', SQLERRM, SQLSTATE;
    end;
$$ language plpgsql;

-- Execute our function in one big transaction to overflow xidcache in backends.
-- Varying repetition count from 100 to 1000 changes hot points from subtrans to
-- multixact.
create or replace function terebonk(scale int) returns void as $$
begin
    insert into pgbench_history (tid, bid, aid, delta, mtime) values (1,2,3,4, now());
    for i in 1..100 loop
        perform such_much_safe_function(6, scale);
    end loop;
end;
$$ language plpgsql;

-- test itself:
-- $pgbench -f sarov2.sql -c 300 -P 1 -T 3000
