WITH routines AS (SELECT
pg_namespace.nspname AS routine_schema,
pg_proc.proname AS routine_name,
pg_proc.proname || '_' || pg_proc.oid AS specific_name,
pg_get_function_identity_arguments(pg_proc.oid) AS parameters,
CASE WHEN pg_proc.prokind='f' THEN 'FUNCTION'
WHEN pg_proc.prokind='p' THEN 'PROCEDURE'
WHEN pg_proc.prokind='w' THEN 'WINDOW FUNCTION' END AS routine_type,
regexp_replace(pg_get_functiondef(pg_proc.oid),'[\r\n]','<br>','g') AS routine_src,
pg_language.lanname AS routine_language
FROM
pg_catalog.pg_proc,
pg_catalog.pg_namespace,
pg_catalog.pg_language
WHERE
pg_proc.pronamespace = pg_namespace.oid
AND pg_proc.prolang = pg_language.oid
AND pg_proc.prokind<>'a'
AND pg_namespace.nspname NOT IN (SELECT schema_name
FROM INFORMATION_SCHEMA.schemata
WHERE schema_name<>'public' AND
schema_owner='postgres' AND schema_name IS NOT NULL)
AND NOT EXISTS (SELECT 1
FROM pg_catalog.pg_depend d
WHERE EXISTS (SELECT 1
FROM pg_catalog.pg_extension e
WHERE d.refobjid=e.oid) AND
d.objid=pg_proc.oid)),
once_used_routines AS (SELECT routine_schema, routine_name, any_value (specific_schema || '.' || regexp_replace(specific_name,'_[0-9]+$','') || '(' || pg_get_function_identity_arguments(translate(substring(specific_name,'_[0-9]+$'),'_','')::int::oid) || ')') AS the_invoker
FROM INFORMATION_SCHEMA.routine_routine_usage
WHERE routine_schema NOT IN (SELECT schema_name
FROM INFORMATION_SCHEMA.schemata
WHERE schema_name<>'public' AND
schema_owner='postgres' AND schema_name IS NOT NULL)
GROUP BY routine_schema, routine_name
HAVING Count(*)=1)
SELECT r.routine_schema, r.routine_name, parameters, routine_type, routine_src, the_invoker
FROM routines AS r INNER JOIN once_used_routines AS our ON r.routine_schema=our.routine_schema AND r.specific_name=our.routine_name
ORDER BY r.routine_schema, r.routine_name, parameters;