create or replace function f_test(v text) returns integer language sql security definer as $$
lock test in exclusive mode;
with w as (select ins.val, test.id from (values (v)) as ins(val) left join test using (val)),
w2 as (insert into test(val) select val from w where w.id is null
returning val, id)
select coalesce(w2.id, w.id) as id from w left join w2 using (val);
$$;