create or replace function pgq.maint_operations(out func_name text, out func_arg text) returns setof record as $$ -- ---------------------------------------------------------------------- -- Function: pgq.maint_operations(0) -- -- Returns list of functions to call for maintenance. -- -- The goal is to avoid hardcoding them into maintenance process. -- -- Function signature: -- Function should take either 1 or 0 arguments and return 1 if it wants -- to be called immediately again, 0 if not. -- -- Returns: -- func_name - Function to call -- func_arg - Optional argument to function (queue name) -- ---------------------------------------------------------------------- declare ops text[]; nrot int4; begin -- rotate step 1 nrot := 0; func_name := 'pgq.maint_rotate_tables_step1'; for func_arg in select queue_name from pgq.queue where queue_rotation_period is not null and queue_switch_step2 is not null and queue_switch_time + queue_rotation_period < current_timestamp order by 1 loop nrot := nrot + 1; return next; end loop; -- rotate step 2 if nrot = 0 then select count(1) from pgq.queue where queue_rotation_period is not null and queue_switch_step2 is null into nrot; end if; if nrot > 0 then func_name := 'pgq.maint_rotate_tables_step2'; func_arg := NULL; return next; end if; -- check if extra field exists perform 1 from pg_attribute where attrelid = 'pgq.queue'::regclass and attname = 'queue_extra_maint'; if found then -- add extra ops for func_arg, ops in select q.queue_name, queue_extra_maint from pgq.queue q where queue_extra_maint is not null order by 1 loop for i in array_lower(ops, 1) .. array_upper(ops, 1) loop func_name = ops[i]; return next; end loop; end loop; end if; -- vacuum tables func_name := 'vacuum'; for func_arg in select * from pgq.maint_tables_to_vacuum() loop return next; end loop; -- -- pgq_node & londiste -- -- although they belong to queue_extra_maint, they are -- common enough so its more effective to handle them here. -- perform 1 from pg_proc p, pg_namespace n where p.pronamespace = n.oid and n.nspname = 'pgq_node' and p.proname = 'maint_watermark'; if found then func_name := 'pgq_node.maint_watermark'; for func_arg in select n.queue_name from pgq_node.node_info n where n.node_type = 'root' loop return next; end loop; end if; perform 1 from pg_proc p, pg_namespace n where p.pronamespace = n.oid and n.nspname = 'londiste' and p.proname = 'root_check_seqs'; if found then func_name := 'londiste.root_check_seqs'; for func_arg in select distinct s.queue_name from londiste.seq_info s, pgq_node.node_info n where s.local and n.node_type = 'root' and n.queue_name = s.queue_name loop return next; end loop; end if; perform 1 from pg_proc p, pg_namespace n where p.pronamespace = n.oid and n.nspname = 'londiste' and p.proname = 'periodic_maintenance'; if found then func_name := 'londiste.periodic_maintenance'; func_arg := NULL; return next; end if; return; end; $$ language plpgsql;