sql/functions/pgq.grant_perms.sql
create or replace function pgq.grant_perms(x_queue_name text)
returns integer as $$
-- ----------------------------------------------------------------------
-- Function: pgq.grant_perms(1)
--
-- Make event tables readable by public.
--
-- Parameters:
-- x_queue_name - Name of the queue.
--
-- Returns:
-- nothing
-- ----------------------------------------------------------------------
declare
q record;
i integer;
pos integer;
tbl_perms text;
seq_perms text;
dst_schema text;
dst_table text;
part_table text;
begin
select * from pgq.queue into q
where queue_name = x_queue_name;
if not found then
raise exception 'Queue not found';
end if;
-- split data table name to components
pos := position('.' in q.queue_data_pfx);
if pos > 0 then
dst_schema := substring(q.queue_data_pfx for pos - 1);
dst_table := substring(q.queue_data_pfx from pos + 1);
else
dst_schema := 'public';
dst_table := q.queue_data_pfx;
end if;
-- tick seq, normal users don't need to modify it
execute 'grant select on ' || pgq.quote_fqname(q.queue_tick_seq) || ' to public';
-- event seq
execute 'grant select on ' || pgq.quote_fqname(q.queue_event_seq) || ' to public';
execute 'grant usage on ' || pgq.quote_fqname(q.queue_event_seq) || ' to pgq_admin';
-- set grants on parent table
perform pgq._grant_perms_from('pgq', 'event_template', dst_schema, dst_table);
-- set grants on real event tables
for i in 0 .. q.queue_ntables - 1 loop
part_table := dst_table || '_' || i::text;
perform pgq._grant_perms_from('pgq', 'event_template', dst_schema, part_table);
end loop;
return 1;
end;
$$ language plpgsql security definer;
create or replace function pgq._grant_perms_from(src_schema text, src_table text, dst_schema text, dst_table text)
returns integer as $$
-- ----------------------------------------------------------------------
-- Function: pgq.grant_perms_from(1)
--
-- Copy grants from one table to another.
-- Workaround for missing GRANTS option for CREATE TABLE LIKE.
-- ----------------------------------------------------------------------
declare
fq_table text;
sql text;
g record;
q_grantee text;
begin
fq_table := quote_ident(dst_schema) || '.' || quote_ident(dst_table);
for g in
select grantor, grantee, privilege_type, is_grantable
from information_schema.table_privileges
where table_schema = src_schema
and table_name = src_table
loop
if g.grantee = 'PUBLIC' then
q_grantee = 'public';
else
q_grantee = quote_ident(g.grantee);
end if;
sql := 'grant ' || g.privilege_type || ' on ' || fq_table
|| ' to ' || q_grantee;
if g.is_grantable = 'YES' then
sql := sql || ' with grant option';
end if;
execute sql;
end loop;
return 1;
end;
$$ language plpgsql strict;