Где хранятся тексты процедур?

Shira
Дата: 04.05.2015 09:42:24
В системных каталогах ANSI(information schema) и PostgreSQL(pg_catalog) хранится очень много интересного. В частности вся информация о таблицах каждой схемы. Есть даже описание процедур, но без собственно их тел. Вопрос - где хранятся и как выцепить тела процедур, их текст на pgPL/SQL или каком другом языке?
Maxim Boguk
Дата: 04.05.2015 10:36:38
Shira,

В pg_catalog и лежат... а точнее в pg_catalog.pg_proc.prosrc

PS: если вы уж туда полезли то все что вас может заинтересовать описано в http://www.postgresql.org/docs/9.4/interactive/catalogs.html

--
Maxim Boguk
www.postgresql-consulting.ru
Shira
Дата: 04.05.2015 11:23:33
Shira,
В pg_catalog и лежат... а точнее в pg_catalog.pg_proc.prosrc
PS: если вы уж туда полезли то все что вас может заинтересовать описано в http://www.postgresql.org/docs/9.4/interactive/catalogs.html

Полез, конечно. И в доке этот пункт посмотрел, но требуемый результат (текст тела процедуры) не получил.
В частности запрос о моей таблице gen_ersave
SELECT pg_get_functiondef(p.oid), p.prosrc
FROM pg_proc p
WHERE proname='gen_ersave'
дал пустое поле, хотя pg_get_functiondef вернул всё корректно.
На других моих функциях удалось получить в лучшем случае комментарии. Может, дело в том, что pg_catalog.pg_proc.prosrc описан как text, и выцеплять его надо как-то по-другому, чем varchar?
Короче, текст:
This tells the function handler how to invoke the function. It might be the actual source code of the function for interpreted languages,...
либо я просто не понял, либо pgPL/SQL по их мнению неявляется интерпретируемым, либо этот текст вообще не соответствует действительности. Главное, что так выцепить текст своей процедуры на pgPL/SQL мне не удалось
Что я делал не так?
Maxim Boguk
Дата: 04.05.2015 12:30:16
Shira
Shira,
В pg_catalog и лежат... а точнее в pg_catalog.pg_proc.prosrc
PS: если вы уж туда полезли то все что вас может заинтересовать описано в http://www.postgresql.org/docs/9.4/interactive/catalogs.html

Полез, конечно. И в доке этот пункт посмотрел, но требуемый результат (текст тела процедуры) не получил.
В частности запрос о моей таблице gen_ersave
SELECT pg_get_functiondef(p.oid), p.prosrc
FROM pg_proc p
WHERE proname='gen_ersave'
дал пустое поле, хотя pg_get_functiondef вернул всё корректно.
На других моих функциях удалось получить в лучшем случае комментарии. Может, дело в том, что pg_catalog.pg_proc.prosrc описан как text, и выцеплять его надо как-то по-другому, чем varchar?
Короче, текст:
This tells the function handler how to invoke the function. It might be the actual source code of the function for interpreted languages,...
либо я просто не понял, либо pgPL/SQL по их мнению неявляется интерпретируемым, либо этот текст вообще не соответствует действительности. Главное, что так выцепить текст своей процедуры на pgPL/SQL мне не удалось
Что я делал не так?


а что дает
\x
select * from  pg_proc WHERE proname='gen_ersave'
?
qwwq
Дата: 04.05.2015 12:59:11
Shira
дал пустое поле
а чем вы смотрели ?

а то у пжодмина есть старая болесть -- он очень содержимое длинных полей показывает как пустоту. вот всё у них так.
вы уж откройте все поля (максим уже посоветовал) -- этой и пары друих записей pg_proc -- и посмотрите, в чём разница.
Shira
Дата: 04.05.2015 12:59:22
Что я делал не так?

а что дает
\x
select * from  pg_proc WHERE proname='gen_ersave'
?

Простите, не понял вопрос. Какой-такой \x ? Что он значит?
Что я должен сделать, чтоб понять, как ответить на Ваш вопрос?
Shira
Дата: 04.05.2015 13:05:56
qwwq
Shira
дал пустое поле
а чем вы смотрели ?
Выполнил запрос в окне редактора SQL
а то у пжодмина есть старая болесть -- он очень содержимое длинных полей показывает как пустоту. вот всё у них так.
вы уж откройте все поля (максим уже посоветовал) -- этой и пары друих записей pg_proc -- и посмотрите, в чём разница.
Открыл. Разницы не увидел. Наверное, всё же не в этом дело. А Вам удавалось увидеть текст тела своей процедуры? Если да, покажите, каким запросом.
Maxim Boguk
Дата: 04.05.2015 13:17:14
Shira
пропущено...

а что дает
\x
select * from  pg_proc WHERE proname='gen_ersave'
?

Простите, не понял вопрос. Какой-такой \x ? Что он значит?
Что я должен сделать, чтоб понять, как ответить на Ваш вопрос?


выполнить в psql естественно
разбираться с потенциальными глюками pg_admin - мне лень.

--
Maxim Boguk
www.postgresql-consulting.ru
qwwq
Дата: 04.05.2015 13:18:24
Shira
А Вам удавалось увидеть текст тела своей процедуры? Если да, покажите, каким запросом.
"Всегда". если это не c-ная ф-я. а ыql или plppgsql OR plperl. и именно таким, ага.

вы этта, вы в psql спросите. чтобы от глюков инструмента отстроиться.

а то "окна запросов" -- они разные бывают. Как вариант -- напишите в вашем любимом "окне запросов" анонимный блок, и выплюньте src в NOTICE -- оно ещё ни разу не жрало текстов.
Maxim Boguk
Дата: 04.05.2015 13:23:59
Shira
Открыл. Разницы не увидел. Наверное, всё же не в этом дело. А Вам удавалось увидеть текст тела своей процедуры? Если да, покажите, каким запросом.



test=# \x
Expanded display is on.
test=# select * from pg_proc where proname='pgcompact_clean_pages_57793';
-[ RECORD 1 ]---+--------------------------------------------------------------------------------
proname | pgcompact_clean_pages_57793
pronamespace | 2200
proowner | 10
prolang | 12727
procost | 100
prorows | 0
provariadic | 0
protransform | -
proisagg | f
proiswindow | f
prosecdef | f
proleakproof | f
proisstrict | f
proretset | f
provolatile | v
pronargs | 5
pronargdefaults | 0
prorettype | 23
proargtypes | 25 25 23 23 23
proallargtypes |
proargmodes |
proargnames | {i_table_ident,i_column_ident,i_to_page,i_page_offset,i_max_tupples_per_page}
proargdefaults |
prosrc |
| DECLARE
| _from_page integer := i_to_page - i_page_offset + 1;
| _min_ctid tid;
| _max_ctid tid;
| _ctid_list tid[];
| _next_ctid_list tid[];
| _ctid tid;
| _loop integer;
| _result_page integer;
| _update_query text :=
| 'UPDATE ONLY ' || i_table_ident ||
| ' SET ' || i_column_ident || ' = ' || i_column_ident ||
| ' WHERE ctid = ANY($1) RETURNING ctid';
| BEGIN
| -- Check page argument values
| IF NOT (
| i_page_offset IS NOT NULL AND i_page_offset >= 1 AND
| i_to_page IS NOT NULL AND i_to_page >= 1 AND
| i_to_page >= i_page_offset)
| THEN
| RAISE EXCEPTION 'Wrong page arguments specified.';
| END IF;
|
| -- Check that session_replication_role is set to replica to
| -- prevent triggers firing
| IF NOT (
| SELECT setting = 'replica'
| FROM pg_catalog.pg_settings
| WHERE name = 'session_replication_role')
| THEN
| RAISE EXCEPTION 'The session_replication_role must be set to replica.';
| END IF;
|
| -- Define minimal and maximal ctid values of the range
| _min_ctid := (_from_page, 1)::text::tid;
| _max_ctid := (i_to_page, i_max_tupples_per_page)::text::tid;
|
| -- Build a list of possible ctid values of the range
| SELECT array_agg((pi, ti)::text::tid)
| INTO _ctid_list
| FROM generate_series(_from_page, i_to_page) AS pi
| CROSS JOIN generate_series(1, i_max_tupples_per_page) AS ti;
|
| <<_outer_loop>>
| FOR _loop IN 1..i_max_tupples_per_page LOOP
| _next_ctid_list := array[]::tid[];
|
| -- Update all the tuples in the range
| FOR _ctid IN EXECUTE _update_query USING _ctid_list
| LOOP
| IF _ctid > _max_ctid THEN
| _result_page := -1;
| EXIT _outer_loop;
| ELSIF _ctid >= _min_ctid THEN
| -- The tuple is still in the range, more updates are needed
| _next_ctid_list := _next_ctid_list || _ctid;
| END IF;
| END LOOP;
|
| _ctid_list := _next_ctid_list;
|
| -- Finish processing if there are no tupples in the range left
| IF coalesce(array_length(_ctid_list, 1), 0) = 0 THEN
| _result_page := _from_page - 1;
| EXIT _outer_loop;
| END IF;
| END LOOP;
|
| -- No result
| IF _loop = i_max_tupples_per_page AND _result_page IS NULL THEN
| RAISE EXCEPTION
| 'Maximal loops count has been reached with no result.';
| END IF;
|
| RETURN _result_page;
| END
probin |
proconfig |
proacl |

--
Maxim Boguk
www.postgresql-consulting.ru