public, которая обращается к объектам (таблицам, типам итд), которые находятся не в public, а в другой схеме (table1 в схеме s1), но при этом видимой по search_path. При этом указываем только имя таблицы / типа, без схемы (т.е. table1 вместо s1.table1). Всё работает.
2. Упоминаем эту функцию в каком-нибудь объекте схемы. Ну например, в какой-нибудь колонке в generated always as.
3. Делаем pg_dump
4. Пытаемся загрузить этот дамп (в другую базу). И вот балалайка: при попытке запуска нашей функции при загрузке дампа таблица table1 не находится. Даже если схема s1 была импортирована раньше. Техническая причина легко выясняется: в начале дампа search_path устанавливается в пустую строку.
а вот что с этим делать? как с помощью pg_dump переносить такие конструкции?
я бы явно схему указывал. Как по мне очень странная штука
ну, для всех объектов всегда указывать схему... так себе :) зачем тогда search_path существует?
Так он указан у функции?
сама функция в схеме public, у неё нормально. Но она использует таблицу s1.table1, не указывая схему, потому что схема в search_path.
ну скорей всего дело в пользователях, search_path - не передается. Как сделать и возможно ли не подскажу
Советую: 1. Читаем документацию (https://www.postgresql.org/docs/current/xfunc-volatility.html ) и убеждаемся, что такая функция — не IMMUTABLE. 2. Читаем документацию (https://www.postgresql.org/docs/current/sql-createtable.html ) и убеждаемся (The generation expression can refer to other columns in the table, but not other generated columns. Any functions and operators used must be immutable. References to other tables are not allowed.), что, т.к. вообще удалось использовать эту функцию в generated, то, значит, мы солгали PostgreSQL в пункте 1 (нагло заявив, что она immutable). 3. Замечаем, что дампу в общем-то всё равно, что снимать (лишь бы читалось). 4. Наблюдаем закономерный итог ("ой, Винни, а куда это я пошёл?") при попытке загрузки дампа. > в начале дампа search_path устанавливается в пустую строку Это security measure — можно поискать в release notes (или в CVE), почему это было сделано. > а вот что с этим делать? Можно сходить почитать -bugs или -hackers и убедиться, что Вы не первые, и отношение разработчиков к таким людям следующее ( https://www.postgresql.org/message-id/1684301.1622084940%40sss.pgh.pa.us ): I will also state categorically that lying about the mutability of a function is a technique that will bite you on the rear, and you will get no sympathy when it does. If it does what you want in version N, fine, but don't whine when it breaks in N+1. А настоящее решение — не лгать PostgreSQL про function volatility, не использовать dirty hacks в своих базах (с помощью триггеров наверняка можно добиться того, чего хотелось, между прочим). > как с помощью pg_dump переносить такие конструкции? Никак (и это одна из причин, почему дамп — не backup).
та же самая проблема возникает, если к таблицам не обращаемся, а обращаемся к типам (объявляем переменные) или вызываем функции из схемы s1. . Так что проблема не обязательно вызвана враньём про immutable.
Покажите repro, в таком случае. Если проблема вызвана чем-то другим, то написать bug report может быть и можно (смотря чем конкретно, там были подобные крайние случаи — не факт, что все их исправили).
https://gist.github.com/portnov/215b3effc980be5f7dabc3bbc5144849
а бэкап, к сожалению, тоже не очень-то поможет: физический бэкап бывает только всего кластера целиком, а перенести надо одну базу (иногда даже одну схему).
Перенесите кластер и удалите все остальные, делов-то. ;) Суть моего утверждения была только в том, что дампы легко (и внезапно для тех, кто почему-то считает себя DBA) ломаются, если разработчики неожиданно добавляют в базу (в смысле DDL) подобную дичь.
Обсуждают сегодня