Много схем - одна функция

Мы хранимые процедуры создаем в схеме public, и генерируем много
схем с одинаковыми наборами таблиц. Каждый пользователь попадает в свою схему. Для этого используем
DISCARD ALL, а затем SET SEARCH_PATH = 'название схемы', public.
Но оказалось, что вызов одной и той же хранимой процедуры в контексте различных схем, возвращает результат, основанный на схеме, в которой произошел ее первый вызов, т.е. search_path в этом случае игнорируется. Похоже Postgre где-то кэширует обращения к таблицам, используемым в хранимой процедуре. Проблема решается если продублировать хранимые процедуры в каждой схеме, но такое решение не выглядит хорошим. Кто встречался с подобной проблемой? Может мы что - то не понимаем?

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Насколько я знаю, хранимая

Насколько я знаю, хранимая процедура КОМПИЛИРУЕТСЯ при её создании.
Могу предположить, что в этот момент в неё зашиваются все обращения к таблицам.
Попробуйте:
ALTER FUNCTION ... RESET ...
и
ALTER FUNCTION ... SET SCHEMA ...
может поможет

Если бы обращения

Если бы обращения формировались в момент компиляции то вызов функции всегда возвращал бы данные из схемы public, а в нашем случае возвращает данные из - той схемы, в контексте которой произошло обращение к функции.

Непонятно. Вы

Непонятно. Вы противоречите:
> Но оказалось, что вызов одной и той же хранимой процедуры в контексте различных схем, возвращает результат, основанный на схеме, в которой произошел ее первый вызов
и
> нашем случае возвращает данные из - той схемы, в контексте которой произошло обращение к функции.

Если последнее, то очевидно - это правильное поведение. Разумеется из какой схемы вызываете, та первой и будет

Нет происходит именно то что

Нет происходит именно то что запоминаются обращения к таблицам в контексте той схемы в которой произошел первый вызов хранимой процедуры, вызовы уже в контексте других схем результат не меняют.

ALTER FUNCTION ... RESET

ALTER FUNCTION ... RESET ...
и
ALTER FUNCTION ... SET SCHEMA ...
пробовали?

не пробовал, ибо мучает вопрос не будет ли вызов функции

с такой инструкцией существенно более дорогим? Ведь его придется делать перед каждым вызовом функции. Ясно, придется экспериментировать...

Я рассчитываю, что достаточно

Я рассчитываю, что достаточно ОДИН раз выполнить ALTER после переноса процедуры в схему, но разумеется я в этом не уверен и экспериментировать действительно придётся.

Проверили, одного alter оказалось недостаточно.

С горя попробовали делать alter на каждый вызов, стало хорошо. Попробовали делать в несколько потоков, получили ожидание на блокировках при выполнении alter function. Жаль, идея неплохая но не прокатило. Поискал на англоязычных форумах Postgre, оказалась проблема давно известная, решать пока не торопятся.

В паблике храним только

В паблике храним только иммутабл функции. Тогда без проблем. Иначе будет то, что у Вас. Выход - только EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ]; с передачей имени схемы параметром или определение его в самой процедуре через переменные окружения. Не исключаю другие варианты решения, т.к. ПГ пользую недавно.

Сейчас мы проблему решили в лоб, просто в каждой схеме

дублируется описание функции. Процесс этот у нас автоматизирован, но не покидает ощущение, что все равно это некрасивое решение, однако, так работает.

Вообще-то странно. У меня

Вообще-то странно. У меня похожая схема таки работает.

CREATE OR REPLACE FUNCTION public.fmr_data_func(VARCHAR,VARCHAR,DATE) RETURNS REFCURSOR AS '
...
OPEN cursor_var FOR
SELECT owner,element,type_element,config
FROM form
WHERE ...
...
' LANGUAGE 'plpgsql' SECURITY DEFINER;

GRANT EXECUTE ON FUNCTION public.fmr_data_func(VARCHAR,VARCHAR,DATE)
TO PUBLIC;

есть пачка схем со своей таблицей `form` и все работает. В пределах сеанса разумеется. Если у Вас нужно переключать схемы в сеансе, то может сделать disconnect/connect?

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023