powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / security definer встроенных функций
21 сообщений из 21, страница 1 из 1
security definer встроенных функций
    #38698764
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет сообществу Postgres.

Необходимо использовать xpath_table в своей хранимке объявленной как security definer.
Но xpath_table "не видит" созданную в моей хранимке времянку. При том, что напрямую курсор из времянки данные возвращает.
День секаса привел к мысли, что проблема в том, что встроенные функции (а может не все?) объявлены как SECURITY INVOKER.

Выхода вижу два:
- либо дать права на времянку исполняющему пользователю
Код: plsql
1.
execute 'grant select on tmp_xml to ' || quote_ident(session_user);



- либо сделать xpath_table security definer
Код: plsql
1.
alter function xpath_table(text,text,text,text,text) security definer



Как поступить правильнее?
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38698806
tadmin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RUS 21,

можно сделать свою обертку к функции и объявить ее security definer.
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38698827
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понял.
По сути моя написанная функция уже и есть обертка и она уже security definer:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
create or replace function dbo.test_xml (out cur1 refcursor,out cur2 refcursor)
as
$BODY$
begin
  create temporary table tmp_xml(ord integer, xmltext text) on commit drop;
  --execute 'alter table tmp_xml owner to ' || quote_ident(session_user);
  insert into tmp_xml (ord, xmltext) values(1, '<?xml version="1.0" encoding="windows-1251" ?><calias><r ords="1"></r></calias>');
  
  open cur1 for
  select * from tmp_xml;

  open cur2 for
  select * from xpath_table('ord','xmltext','tmp_xml','/calias/r/@ords','true') as t(ord integer, orders integer);
end;    
$BODY$
language plpgsql 
security definer
;


Вот в таком виде запуск из под непривилегированного пользователя дает permission denied for relation tmp_xml
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699100
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RUS 21,

какая у вас версия сервера? Покажите select version();
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699119
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Последнего недавно качал.
Код: sql
1.
PostgreSQL 9.3.4 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-52), 64-bit
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699157
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RUS 21
Код: sql
1.
2.
3.
4.
5.
6.
  create temporary table tmp_xml(ord integer, xmltext text) on commit drop;
...
  open cur2 for
...
security definer
;


Вот в таком виде запуск из под непривилегированного пользователя дает permission denied for relation tmp_xml Ошибку даёт не запуск самой хранимки, а чтение из второго курсора. Вы создали таблицу и курсор под пользователем user1, а читать из таблицы и курсора пытаетесь под пользователем user2.
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699234
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЁшОшибку даёт не запуск самой хранимки, а чтение из второго курсора. Вы создали таблицу и курсор под пользователем user1, а читать из таблицы и курсора пытаетесь под пользователем user2.
Согласен. Ошибка вылетатет во время fetch.
И что вы посоветуете в таком случае?
Задача - организовать работу с БД максимально урезанных в правах пользователей посредством хранимок владельца основной схемы данных.
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699278
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще интересное конечно поведение
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
begin;

create role user1;
create role user2;
create function test(OUT cur refcursor) returns refcursor language plpgsql
as $$
declare
  res text;
begin
  open cur for select current_user union all select current_user;
  fetch cur into res;
  raise notice 'test fetch(%): %', current_user, res;
end
$$ security definer;
alter function test() owner to user1;
grant execute on function test() to user2;

set role user2;

select test();
fetch all "<unnamed portal 1>";

rollback;

$ psql -Xq -U postgres -f test.sql test
psql:test.sql:20: NOTICE:  test fetch(user1): user1
        test        
--------------------
 <unnamed portal 1>
(1 row)

 current_user 
--------------
 user2
(1 row)



первая строчка курсора выполняется под user1, а вторая, под user2 :-)

PS: по поводу вопроса — не знаю :)
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699472
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Oracle создаешь хранимку как definer (по-умолчанию), открываешь курсор и не паришься о правах конкретного пользователя на таблицы, используемые в этой хранимке. Лишь бы дать эти права владельцу хранимок и дать права пльзователям на запуск этих хранимок.
А тут получается, если в хранимке создаются объекты (времянки) и выплевываемый курсор использует их, то в момент фетча у меня не хватит прав..
В общем, я склоняюсь к мысли раздавать права на времянки (первый вариант).

Только вопрос: как отработает создание временной таблицы и раздача прав на неё current_user при одновременном запуске такой хранимки двумя пользователями?
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699489
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RUS 21В Oracle создаешь хранимку как definer (по-умолчанию), открываешь курсор и не паришься о правах конкретного пользователя на таблицы, используемые в этой хранимке. Лишь бы дать эти права владельцу хранимок и дать права пльзователям на запуск этих хранимок.
А тут получается, если в хранимке создаются объекты (времянки) и выплевываемый курсор использует их, то в момент фетча у меня не хватит прав..
В общем, я склоняюсь к мысли раздавать права на времянки (первый вариант).

Только вопрос: как отработает создание временной таблицы и раздача прав на неё current_user при одновременном запуске такой хранимки двумя пользователями?

1)Временные таблицы - они локальны для backend так что можно хоть 200 одинаковых временных таблиц сделать в 200 коннектах (и у каждого backend она своя будет со своей структурой и правами).

2)Временные таблицы в PostgreSQL очень дорогое решение, я бы посоветовал стараться без них делать а через return query возвращать весь ответ из хранимки, и если уж надо потом по кускам вычитывать - открывать курсор снаружи функии.
Или вам 2+ разных result set хочется из функции вернуть? Но это всеравно можно без временных таблиц сделать.


--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699589
Sergei.Agalakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как вариант - создать нормальную nologging таблицу, дать на нее права всем, иметь в ней колонку PID или другой идентификатор сессии. Так в принципе можно разделять данные между сессиями. Ну и обдумать уборку мусора из этой таблицы.
Но если размеры разделяемых между сессиями данных позволяют, то лучше избежать временных таблиц вообще, как Максим советует.
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38699894
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

да, чаще всего курсоров несколько и даже если один, то для клиента-приложения удобнее оперировать refcusor-ами.
Спасибо за информацию. Временные таблицы будут использоваться только если есть сложная обработка/подготовка данных.
В Oracle в выручали коллекции, ну и те же времянки (которые создаются заранее, а не по ходу действия в исполняемой хранимке).

Sergei.Agalakov,

спасибо. Идея понятна, но, думаю, это будет слишком.Оставим как запасной вариант, если создание времянок будет заметно тормозить.
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38701474
UKY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
UKY
Гость
Maxim Boguk2)Временные таблицы в PostgreSQL очень дорогое решение
Максим, а что в них дорогого? Если то, что они пушут в WAL, то их можно же UNLOGGED сделать.
Или есть ещё какие-то тормоза?
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38701827
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UKYMaxim Boguk2)Временные таблицы в PostgreSQL очень дорогое решение
Максим, а что в них дорогого? Если то, что они пушут в WAL, то их можно же UNLOGGED сделать.
Или есть ещё какие-то тормоза?

В wal они конечно не идут... но вот создание временной таблицы это DDL со всем его overhead немаленьким.

Вот 3 примера на моей тестовой базе:

меряется время 100.000 вызовов в формате begin; select test(); commit; (в 1 коннекте):

select фукция минимальная:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE OR REPLACE FUNCTION test() RETURNS void
    LANGUAGE plpgsql
    AS $$
declare
  i integer;
begin
  i := (random()*10000)::int;
end
$$;


100.000 вызовов - 10секунд т.е. 0.1ms на вызов

тоже самое + запись 1 строки в обычную таблицу
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE OR REPLACE FUNCTION test() RETURNS void
    LANGUAGE plpgsql
    AS $$
declare
  i integer;
begin
  i := (random()*10000)::int;
  insert into test (id) values (i);  
end
$$;


100.000 вызовов - теже 10 секунд

А вот теперь интересное - добавляем создание временной таблицы
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE OR REPLACE FUNCTION test() RETURNS void
    LANGUAGE plpgsql
    AS $$
declare
  i integer;
begin
  i := (random()*10000)::int;
  create temporary table test_tbl (id integer) on commit drop;
  insert into test_tbl (id) values (i);  
end
$$;


100.000 вызовов занимают теперь заняло 60 секунд... т.е. в 6 раз дольше...


Временные таблицы сами по себе быстрые а вот их создание - не очень... правильный режим использования - надо заранее их создавать в коннекте с базой и дальше пользоваться не создавая заново каждый раз внутри хранимки... или использовать для тяжелых и сложных расчетов где overhead на создание таблицы будет незаметен (но в 99% случаем можно обойтись без них).

--Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38963197
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЁшВообще интересное конечно поведение
С разницей в год наступаю на те же грабли))

1) Если в последовательности вызываемых хранимок есть security invoker, то при fetch курсора execution context открываемых курсоров для security-invoker-хранимок "сваливается" с юзера-владельца security-definer-хранимки в контекст пользователя, запустившего самую "верхнюю" хранимку.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
drop function if exists public.t1();
drop function if exists public.t2();
drop function if exists public.t3();
drop role if exists role1;
drop role if exists role2;

create role role1 login;
create role role2 login;
create or replace function public.t1(cur out refcursor, val out varchar)
as
$$
begin
  raise info '%','t1:'||current_user;
  open cur for select public.t2();
  val:=current_user;
end;
$$
language plpgsql 
security definer;
alter function public.t1() owner to role1;

create or replace function public.t2()
returns void as
$$
begin
  raise info '%','t2:'||current_user;
  perform public.t3();
end;
$$
language plpgsql 
security INVOKER;
alter function public.t2() owner to role1;

create or replace function public.t3()
returns void as
$$
begin
  raise info '%','t3:'||current_user;
end;
$$
language plpgsql 
security INVOKER;
alter function public.t3() owner to role1;

set role role2;

begin;
select current_user, public.t1();
fetch all from "<unnamed portal 1>";
rollback;



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
ИНФОРМАЦИЯ:  t1:role1

 current_user |              t1
--------------+------------------------------
 role2        | ("<unnamed portal 1>",role1)

ИНФОРМАЦИЯ:  t2:role2
ИНФОРМАЦИЯ:  t3:role2



2)Но если нет работы с курсорами, то все происходит как и предполагается при работе с security-definer-хранимками.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
drop function if exists public.t1();
drop function if exists public.t2();
drop function if exists public.t3();
drop role if exists role1;
drop role if exists role2;

create role role1 login;
create role role2 login;

create or replace function public.t1(val out varchar)
as
$$
begin
  raise info '%','t1:'||current_user;
  perform public.t2();
end;
$$
language plpgsql 
security definer;
alter function public.t1() owner to role1;

create or replace function public.t2()
returns void as
$$
begin
  raise info '%','t2:'||current_user;
  perform public.t3();
end;
$$
language plpgsql 
security INVOKER;
alter function public.t2() owner to role1;

create or replace function public.t3()
returns void as
$$
begin
  raise info '%','t3:'||current_user;
end;
$$
language plpgsql 
security INVOKER;
alter function public.t3() owner to role1;

set role role2;

select current_user, public.t1();


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
ИНФОРМАЦИЯ:  t1:role1
ИНФОРМАЦИЯ:  t2:role1
ИНФОРМАЦИЯ:  t3:role1
 current_user
--------------
 role2



3)Вдогонку. Если в первом случае fetch происходит уже под верхним(сессионным) пользователем и его контекст оказывается "главнее", то если в последовательности хранимок все они security definer, то "сваливания" контекста не происходит и security-definer-матрешка отрабатывает как и должна.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
drop function if exists public.t1();
drop function if exists public.t2();
drop function if exists public.t3();
drop role if exists role1;
drop role if exists role2;

create role role1 login;
create role role2 login;
create or replace function public.t1(cur out refcursor, val out varchar)
as
$$
begin
  raise info '%','t1:'||current_user;
  open cur for select public.t2();
  val:=current_user;
end;
$$
language plpgsql 
security definer;
alter function public.t1() owner to role1;

create or replace function public.t2()
returns void as
$$
begin
  raise info '%','t2:'||current_user;
  perform public.t3();
end;
$$
language plpgsql 
security DEFINER;
alter function public.t2() owner to role1;

create or replace function public.t3()
returns void as
$$
begin
  raise info '%','t3:'||current_user;
end;
$$
language plpgsql 
security DEFINER;
alter function public.t3() owner to role1;

set role role2;

begin;
select current_user, public.t1();
fetch all from "<unnamed portal 1>";
rollback;


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
ИНФОРМАЦИЯ:  t1:role1

 current_user |              t1
--------------+------------------------------
 role2        | ("<unnamed portal 1>",role1)

ИНФОРМАЦИЯ:  t2:role1
ИНФОРМАЦИЯ:  t3:role1



По мне, так либо всегда контекст владельца (что есть суть security definer), либо всегда контекст сессионного юзера (тогда нафиг пытались реализовать security definer).

Ёш, Maxim Boguk,
не тянет на bug?
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38967276
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RUS 21,

Я погонял ваши варианты.
В общем тут вот какое дело: конструкция
Код: plaintext
open cur for select ...;
просто сохраняет текст запроса в связке с именем курсора (без всякого security context). Реального выполнения запроса при этом не происходит (это важно).
Реально запрос выполняется при ПЕРВОМ вызове FETCH на этом курсоре.

Мне кажется что Bug report писать бессмысленно, скажут что фича.

Workaround (костыль! костыль!) можно вот такой вот сделать (выполнить cursor запрос внутри SECURITY DEFINER хранимки перед тем как его отдавать):

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
drop function if exists public.t1(refcursor);
drop function if exists public.t2();
drop role if exists role1;
drop role if exists role2;

create role role1 login;
create role role2 login;

create or replace function public.t1(refcursor) RETURNS refcursor
as
$$
begin
  raise info 't1 current_user: %', current_user;
  open $1 SCROLL for select public.t2();
  MOVE FORWARD FROM $1;
  MOVE BACKWARD FROM $1;
  RETURN $1;
end;
$$
language plpgsql 
security definer;
alter function public.t1(refcursor) owner to role1;

create or replace function public.t2() RETURNS SETOF INTEGER
as
$$
begin
  raise info '%','t2:'||current_user;
  RETURN NEXT 1;
  RETURN NEXT 2;
  RETURN;
end;
$$
language plpgsql 
security INVOKER;
alter function public.t2() owner to role1;

set role role2;
begin;
select current_user;
select * FROM public.t1('test_cur');
fetch ALL from test_cur;
rollback;



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
postgres=# set role role2;
SET
postgres=> begin;
BEGIN
postgres=> select current_user;
 current_user
--------------
 role2
(1 row)

postgres=> select * FROM public.t1('test_cur');
INFO:  t1 current_user: role1
INFO:  t2:role1
CONTEXT:  PL/pgSQL function t1(refcursor) line 5 at FETCH
    t1
----------
 test_cur
(1 row)

postgres=> fetch ALL from test_cur;
 t2
----
  1
  2
(2 rows)

postgres=> rollback;
ROLLBACK

Может у кого то идеи будут лучше как красивее заэнфорсить инициализацию запроса из курсора перед тем как его из хранимки отдавать.

PS: мое личное мнение что это баг конечно.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38967547
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,
спасибо за проявленный интерес к теме.

Maxim BogukРеально запрос выполняется при ПЕРВОМ вызове FETCH на этом курсоре.
Мне тоже кажется, что это баг в обработке/хранении execution context при наличии вложенности хранимых процедур.
Потому как в одном случае контекст доходит до этапа fetch правильно, а в другом, вследствие некорректной обработки, "сбрасывается".

Maxim Bogukкостыль! костыль!
А какой на ваш взгляд у этого костыля overhead (особенно в случае тяжелых для выборки первой записи планов)? Наверное незначительный? Что мы в клиенте начнем фетчить курсор, что мы в хранимке дернем одну запись..Возможно для курсора типа scroll какие-то дополнительные структуры создаются..

PS: в своем случае пока изменил тип хранимок pgagent`а на security definer.
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38967721
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukRUS 21,
Мне кажется что Bug report писать бессмысленно, скажут что фича.
и будут правы. т.к. по выходу из security definer мы вернулись в контекст invoker, а в нем на выполнение запроса курсора нет прав.

это, думается, простое и стройное поведение.

если же костылем открыли -- то ещё в контексте definer -- права и были.
опять простое и стройное поведение.

-- немного добавил ясности
которая и так была
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
BEGIN;
drop function if exists public.t1(refcursor);
drop function if exists public.t2();
drop role if exists role1;
drop role if exists role2;

create role role1 login;
create role role2 login;

create or replace function public.t1(refcursor) RETURNS refcursor
as
$$
begin
  raise info 't1 current_user: %', current_user;
  open $1 SCROLL for select public.t2();
  MOVE FORWARD FROM $1;
  MOVE BACKWARD FROM $1;
  RETURN $1;
end;
$$
language plpgsql 
security definer;
alter function public.t1(refcursor) owner to role1;

create or replace function public.t2() RETURNS SETOF text
as
$$
begin
  raise info '%','t2:'||current_user;
  RETURN NEXT current_user;
  RETURN NEXT current_user;
  RETURN;
end;
$$
language plpgsql 
security INVOKER;
alter function public.t2() owner to role1;

set role role2;
-- begin;
select current_user;
select * FROM public.t1('test_cur');
fetch ALL from test_cur;
rollback;



-------------------
иначе надо объявлять с каким-то [отсутствующем пока в синтаксе] модификатором (добавить SQL кляузу в ) [DECLARE|OPEN] .... WITH ROLE ... ; -- тогда тоже будет простое и стройное поведение -- в момент OPEN проверяются права в текущем контексте , в момент fetch -- не проверяется ничто, ибо проверка перенесена в OPEN; (а все ф-ии в курсоре, если есть, выполняются в контексте ROLE. в т.ч. и "current_user" ).

или включать дурочку [идти в отказ] в момент уже [DECLARE|OPEN], всегда и везде.

ну и заодно "with hold" хотелось бы для plpgsql-cursors. иногда, когда соединение за клиентом можно удержать без ненужного (и плохо контролируемого) висяка клиентской транзы. Или его таки можно через динамику из хранимки открыть как SQL-cursor?
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38986676
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И снова security definer))
Задались вопросом почему plpgsql-функции работают быстрее, чем sql.
Pavel Stehule говорит, что нормальная имутабл-функция должна встраиваться в запрос и только тогда можно получить(негарантированное) ускорение от более оптимального плана выполнения и может быть обогнать кэшированный план plpgsql-функции..
http://www.postgresql.org/message-id/CAFj8pRCTRo-Y3+M2uYGjt2d4J0=KhRfbqRpSA1=rxbBkYoy4MQ@mail.gmail.com]http://www.postgresql.org/message-id/CAFj8pRCTRo-Y3 M2uYGjt2d4J0=KhRfbqRpSA1=rxbBkYoy4MQ@mail.gmail.com
И так вроде бы и получается. Видим в плане развернутую sql-функцию..
НО! Если функция security definer, то фигвам.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE OR REPLACE FUNCTION public.fx1(integer, integer)
 RETURNS integer
 LANGUAGE sql
AS $function$
select coalesce($1, $2)
$function$ immutable;

CREATE OR REPLACE FUNCTION public.fx2(integer, integer)
 RETURNS integer
 LANGUAGE sql
AS $function$
select coalesce($1, $2)
$function$ security definer immutable;



Код: sql
1.
explain verbose select fx1(random()::int, random()::int);


Код: plaintext
1.
2.
Result  (cost=0.00..0.02 rows=1 width=0)
Output: COALESCE((random())::integer, (random())::integer)

Код: sql
1.
explain verbose select fx2(random()::int, random()::int);



Код: plaintext
1.
2.
Result  (cost=0.00..0.27 rows=1 width=0)
Output: fx2((random())::integer, (random())::integer)

Код: sql
1.
select * from pg_proc where proname like 'fx%';





О чем говорят мужчины- Немцы, как жить дальше?
- Как, как? Каком кверху!
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38986686
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RUS 21,

И это вполне логично... нельзя встроить (Inline) подзапрос выполняемый от другого пользователя (а security definer именно это).
Такое поведение вполне ожидаемо и предсказуемо.

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
security definer встроенных функций
    #38986730
Фотография RUS 21
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim Boguk,

соглашусь. И в исходниках нашли
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
        /*
	 * Forget it if the function is not SQL-language or has other showstopper
	 * properties.  (The nargs check is just paranoia.)
	 */
	if (funcform->prolang != SQLlanguageId ||
		funcform->prosecdef ||
		funcform->proretset ||
		funcform->prorettype == RECORDOID ||
		!heap_attisnull(func_tuple, Anum_pg_proc_proconfig) ||
		funcform->pronargs != list_length(args))
		return NULL;
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / security definer встроенных функций
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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