Вы должны когда-либо манипулировать системными каталогами напрямую, только если точно знаете, что делаете. Это может иметь неожиданные побочные эффекты. Или вы можете повредить базу данных (или весь кластер базы данных) без возможности восстановления.
Ответ Джереми , хотя и делает свое дело, не рекомендуется для широкой публики. Это безоговорочно меняет все функции в схеме. Вы уверены, что не затронуты системные функции или функции, установленные дополнительным модулем?
Также было бы бессмысленно менять владельца функций, которые уже принадлежат назначенному владельцу.
Во-первых, проверьте, REASSIGN OWNED
может ли это работать на вас:
изменить владельца объектов базы данных, принадлежащих роли базы данных
Вы должны перечислить все роли, от которых следует отказаться в явном виде. Но это также переназначает функции .
Чтобы назначить все функции (и никакие другие объекты) в данной схеме новому владельцу (необязательно независимо от предыдущего владельца):
SELECT string_agg('ALTER FUNCTION ' || oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
FROM pg_catalog.pg_proc p
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'public';
-- AND p.relowner <> (SELECT oid FROM pg_roles WHERE rolname = 'foo')
-- AND p.proname ~~ 'f_%'
Это генерирует канонические команды SQLALTER FUNCTION ...
для изменения всех функций (в указанной схеме). Вы можете проверить команды перед их выполнением - по одной или все сразу:
ALTER FUNCTION public.bar(text, text) OWNER TO foo;
ALTER FUNCTION public.foo(x integer) OWNER TO foo;
...
Я включил некоторые закомментированные WHERE
предложения, которые вы можете использовать для фильтрации результатов.
Приведение к regprocedure
приводит к действительному имени функции с параметрами, где необходимо использовать двойные кавычки, а схему - с указанием, где это необходимо для текущего search_path
.
Агрегатная функция string_agg () требует PostgreSQL 9.0 или более поздней версии . В старой версии заменить на array_agg()
и array_to_string()
.
Вы можете поместить все это в DO
утверждение или функцию, как показано в следующем ответе:
В Postgres 9.5 или новее вы можете упростить запрос, используя новые типы идентификаторов объектов regnamespace
иregrole
:
SELECT string_agg('ALTER FUNCTION '|| oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
FROM pg_catalog.pg_proc
WHERE pronamespace = 'public'::regnamespace;
-- AND relowner <> 'foo'::regrole
-- AND proname ~~ 'f_%'
pg_proc.proisagg
заменяется на стр 11. Примечания к выпуску сказать: Заменить системную таблицуpg_proc
«sproisagg
иproiswindow
сprokind
(Peter Eisentraut)`