powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / вызов процедуры от имени другого пользователя
4 сообщений из 4, страница 1 из 1
вызов процедуры от имени другого пользователя
    #39758423
BigBudda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Подскажите, пожалуйста, как вызвать выполнение процедуры от имени другого пользователя в postgresql?
...
Рейтинг: 0 / 0
вызов процедуры от имени другого пользователя
    #39758431
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BigBudda,

security definer?
...
Рейтинг: 0 / 0
вызов процедуры от имени другого пользователя
    #39759837
BigBudda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Melkij,спасибо! То, что нужно.

Однако у меня как всегда возникли вопросы. Оно работает. Но гораздо медленнее, чем выполнение процедуры/функции от её владельца. Тренируюсь исключительно на кошках, в тестовой БД.

Под пользователем postgres создал схему nsi (справочник), в ней таблицу nsi_dictionary и функцию по вставке данных в эту таблицу.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
test=# \d nsi.nsi_dictionary;
                                           Table "nsi.nsi_dictionary"
   Column    |           Type           | Collation | Nullable |                    Default
-------------+--------------------------+-----------+----------+------------------------------------------------
 id          | integer                  |           | not null | nextval('nsi.nsi_dictionary_id_seq'::regclass)
 change_date | timestamp with time zone |           | not null |
 nsi_value   | text                     |           |          |
Indexes:
    "nsi_dictionary_pkey" PRIMARY KEY, btree (id)


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE OR REPLACE FUNCTION nsi.add_data_nsi (text) RETURNS timestamp with time zone AS '
DECLARE
nsi_value ALIAS FOR $1;
right_now timestamp;
BEGIN
right_now := ''now'';
INSERT INTO nsi.nsi_dictionary VALUES (default, right_now, nsi_value);
RETURN right_now;
END;
'
LANGUAGE 'plpgsql'
SECURITY DEFINER
COST 10;



Добавил нового пользователя в БД:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
test=# create role client;
CREATE ROLE
test=# alter role client with login;
ALTER ROLE
postgres=# GRANT CONNECT ON DATABASE test TO client;
GRANT
test=# grant execute on function nsi.add_data_nsi to client;
GRANT



Выполнил и увидел, что под владельцем выполнилось быстрее, чем под сторонним пользователем.
Сперва выполнял под владельцем.
Начал тестировать с explain (analyze,buffers) select nsi.add_data_nsi('sql.ru');

Код: plsql
1.
2.
3.
4.
5.
 Result  (cost=0.00..0.04 rows=1 width=8) (actual time=0.161..0.162 rows=1 loops=1)
   Buffers: shared hit=3
 Planning Time: 0.031 ms
 Execution Time: 0.182 ms
(4 rows)


и под владельцем и под сторонним пользователем примерно одинаково.

Вопросы:
1. Может ли использование SECURITY DEFINER привести к дополнительным накладным расходам и тормозить при массовых операциях? Те ситуации, когда справочник обновляется слишком часто.
2. Какой cost выставить для обновления справочника? Например, в справочнике 10000 записей. Планируется что в среднем в месяц будет его прирост на 50% максимум.
...
Рейтинг: 0 / 0
вызов процедуры от имени другого пользователя
    #39759884
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BigBudda,

* На скорость работы SECURITY DEFINER или INVOKER может влиять только косвенно.
Например это может влиять на то, с какими объектами работает функция.
Но не в этом примере, здесь схема у таблицы указана явно, что исключает разные толкования.

* На cost для такой функции можно забить.

* Почитайте про права по умолчанию на выполнение функций.
Если коротко, то по умолчанию все пользователи могут выполнять любую созданную функцию.
Поэтому сначала нужно сделать revoke execute from public и только потом grant execute кому надо.
Для SECURITY DEFINER это очень актуально.

* Параметрам функции можно давать имена f(nsi_value text), тогда не нужно использовать alias.

* insert умеет возвращать значение (insert .. returning), можно обойтись без right_now

* в этой функции можно легко без plpgsql обойтись:
Код: sql
1.
2.
3.
4.
CREATE OR REPLACE FUNCTION nsi.add_data_nsi (nsi_value text) RETURNS timestamp with time zone 
AS $$ INSERT INTO nsi.nsi_dictionary VALUES (default, now(), nsi_value) RETURNING change_date; $$
LANGUAGE sql
SECURITY DEFINER
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / вызов процедуры от имени другого пользователя
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]