#!/bin/bash

function get_query {
read -r -d '' QUERY <<HEREDOCEND
do language plpgsql \$FN\$
declare
  vi bigint := 0;
begin
  while true loop
    if vi % 1000 = 0 then
      raise notice 'redefine function progress %', vi;
    end if;
    execute format('create or replace function test_fn$1() returns text as \$BODY\$
                    begin
                      return ''version %1\$s'';
                    end;
                    \$BODY\$ language plpgsql',
                    vi);
    commit;
    vi := vi + 1;
  end loop;
end;
\$FN\$;
HEREDOCEND
echo "$QUERY"
}

CALL_FN=$(mktemp)
cat << 'HEREDOCEND' > "$CALL_FN"
do language plpgsql $$
declare
  vall bigint := 10000000;
  vi bigint;
begin
  for vi in select i from generate_series(1, vall) i
  loop
    if vi % 200000 = 0 then
      raise notice 'progress: % of %', vi, vall;
    end if;
    perform test_fn1(), test_fn2(), test_fn3(), test_fn4();
  end loop;
end;
$$;
HEREDOCEND

vacuumdb --all --full --freeze --analyze

# Connection1-4: continuosly redefine function in background
psql -Xe -c "$(get_query 1)" &
psql -Xe -c "$(get_query 2)" &
psql -Xe -c "$(get_query 3)" &
psql -Xe -c "$(get_query 4)" &

# Connection2: select from function in transaction
pgbench --no-vacuum --client=1 --transactions=10 --file="$CALL_FN"

jobs -pr | xargs --no-run-if-empty kill
wait

