Postgres 8.3 Запрос полного определения функции с помощью запроса

Можно ли получить полное определение функции (с параметрами и т. д.) С помощью SQL-запроса?

PostgreSQL 8.3 является устаревшим и больше не поддерживается. Вы можете рассмотреть возможность обновления до версии PostgreSQL, которая изначально поддерживает этот stackoverflow.com/questions/6898453/… и все еще поддерживается.

Raymond Nijland 27.10.2018 01:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
93
1

Ответы 1

Эта функция или представление (выполняющие аналогичные действия) работают с Postgres 8.3.

CREATE AGGREGATE public.textcat_all(
  basetype    = text,
  sfunc       = textcat,
  stype       = text,
  initcond    = ''
);

CREATE OR REPLACE FUNCTION public.getfunctionddl(functionOid oid)
  RETURNS text AS
$BODY$
DECLARE
    funcschema text;
    funcname text = NULL;
    paranames text;
    paramodes text;
    paratypes text;
    paraintypes text;
    function_body text = NULL;
    paranames_array text[];
    paramodes_array text[];
    paratypes_array text[];
    params_sql text = '';
    type_name text = '';
    return_type text;
    params_sql_no_name text ='';
    grants text;
    proc_owner text;
    proacl_txt text;
    lanname_txt text;
    function_sql text;
    upper_array int;
    in_param_cnt int = 0;
    out_param_cnt int = 0;
    prosecdef_b bool;
    pro_volatile text;
    pro_isstrict bool;
BEGIN
SELECT proargtypes, proallargtypes, proargnames, proargmodes, prosrc, ns.nspname, p.proname, prorettype, proacl, lanname, prosecdef, rolname, provolatile, proisstrict
INTO paraintypes, paratypes, paranames, paramodes, function_body, funcschema, funcname, return_type, proacl_txt, lanname_txt, prosecdef_b, proc_owner, pro_volatile, pro_isstrict
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE p.oid = functionOid
AND lanname <> 'internal';

IF COALESCE(funcname, '') = '' THEN
    RETURN NULL;
END IF;

paratypes := REPLACE(COALESCE(paratypes, paraintypes), ',', ' ');
return_type := format_type(return_type::oid,NULL);
return_type := CASE WHEN return_type = 'character varying' THEN 'varchar' ELSE return_type END;
if paranames IS NULL OR paranames = '' THEN
    params_sql := '()';
    params_sql_no_name := '()';
ELSE
    paratypes := REPLACE(REPLACE(paratypes, '{', ''), '}', '');
    paranames := REPLACE(REPLACE(paranames, '{', ''), '}', '');
    paramodes := REPLACE(REPLACE(paramodes, '{', ''), '}', '');

    paratypes_array:=string_to_array(paratypes,' ');
    paranames_array:=string_to_array(paranames,',');
    paramodes_array:=string_to_array(paramodes,',');
    upper_array := array_upper(paratypes_array,1);
    params_sql := '(' || CASE WHEN upper_array > 5 THEN '
    ' ELSE '' END;
    params_sql_no_name := '(';
    FOR i IN array_lower(paratypes_array,1) .. array_upper(paratypes_array,1)
    LOOP
        type_name := format_type(paratypes_array[i]::oid, NULL);
        type_name := CASE WHEN type_name = 'character varying' THEN 'varchar' ELSE type_name END;
        params_sql := params_sql || CASE WHEN paramodes IS NULL OR paramodes = '' THEN '' WHEN paramodes_array[i] = 'o' THEN 'OUT ' ELSE '' END || paranames_array[i] || ' ' || type_name || CASE WHEN i = upper_array THEN ')' WHEN upper_array <= 5 THEN ', ' ELSE ',
    ' END;
        params_sql_no_name := params_sql_no_name || CASE WHEN paramodes IS NULL OR paramodes = '' THEN '' WHEN paramodes_array[i] = 'o' THEN 'OUT ' ELSE '' END || type_name || CASE WHEN i = upper_array THEN ')' ELSE ',' END;
        in_param_cnt := in_param_cnt + CASE WHEN paramodes IS NULL OR paramodes = '' THEN 1 WHEN paramodes_array[i] = 'o' THEN 0 ELSE 1 END;
        out_param_cnt := out_param_cnt + CASE WHEN paramodes IS NULL OR paramodes = '' THEN 0 WHEN paramodes_array[i] = 'o' THEN 1 ELSE 0 END;
    END LOOP;
END IF;

params_sql_no_name := LOWER(quote_ident(funcschema) || '.' || quote_ident(funcname)) || params_sql_no_name || '';
params_sql := quote_ident(funcschema) || '.' || quote_ident(funcname) || params_sql;

SELECT public.textcat_all('GRANT EXECUTE ON FUNCTION ' || params_sql_no_name || ' TO ' || quote_ident(grantee) || ';

') INTO grants
FROM(SELECT
      substring(a, 1, position('=X' in a) -1) as grantee
--  , substring(a, position('=X' in a) + 3, char_length(a) - position('=X' in a)) as grantor_name
From regexp_split_to_table(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(proacl_txt, '}', ''), '{', ''), CHR(34) || chr(92), ''), CHR(34), ''), chr(92), ''), ',') a)k
WHERE grantee <> proc_owner
AND grantee <> '';

function_sql := '-- ' || params_sql_no_name || '
' || CASE WHEN in_param_cnt + out_param_cnt > 0 THEN '-- PARAMS ALL: ' || CAST(in_param_cnt + out_param_cnt as char(3)) || ', IN: ' || cast(in_param_cnt as char(3)) || ', OUT ' || CAST(out_param_cnt as char(3)) || '
' ELSE '' END || '
-- DROP FUNCTION IF EXISTS ' || params_sql_no_name || ';
-- DROP FUNCTION IF EXISTS ' || params_sql_no_name || ' CASCADE;

CREATE OR REPLACE FUNCTION ' || params_sql || '
' || 'RETURNS ' || CASE WHEN return_type = 'record' then 'SETOF record' ELSE return_type END || '
LANGUAGE ' || lanname_txt || CASE WHEN pro_volatile = 'i' THEN ' IMMUTABLE' WHEN pro_volatile = 's' THEN ' STABLE' ELSE '' END || CASE WHEN pro_isstrict = true THEN ' RETURNS NULL ON NULL INPUT' ELSE '' END || CASE WHEN prosecdef_b = true THEN ' SECURITY DEFINER' ELSE '' END || '
AS $' || '$' || COALESCE(function_body, '') || '$' || '$;';

function_sql := function_sql || '

-- ALTER FUNCTION ' || params_sql_no_name || ' OWNER TO ' || quote_ident(proc_owner) || ';' || COALESCE('

' || grants, '');

RETURN function_sql;
END $BODY$ LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION public.getfunctionddl(schema_name_like varchar(256), function_name_like varchar(256), OUT schema_name varchar(256), OUT function_name varchar(256), OUT owner varchar(256), OUT func_lang varchar(256), OUT arg_cnt smallint, OUT func_oid oid, OUT ddl text)
RETURNS SETOF record AS $$
SELECT
      CAST(ns.nspname as varchar(256)) as schema_name
    , CAST(p.proname as varchar(256)) as proc_name
    , cast(rolname as varchar(256)) as owner
    , CAST(lanname as varchar(256)) as func_lang
    , p.pronargs as arg_cnt
    , p.oid as func_oid
    , public.getfunctionddl(p.oid) as ddl
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE ns.nspname ILIKE lower(coalesce($1, '%'))
AND p.proname ILIKE lower(coalesce($2, '%'))
AND lanname <> 'internal'
ORDER BY ns.nspname, p.proname, p.oid;
$$ LANGUAGE SQL;

CREATE OR REPLACE VIEW public.vw_functionddl
AS
SELECT
      CAST(ns.nspname as varchar(256)) as schema_name
    , CAST(p.proname as varchar(256)) as proc_name
    , cast(rolname as varchar(256)) as owner
    , CAST(lanname as varchar(256)) as func_lang
    , p.pronargs as arg_cnt
    , p.oid as func_oid
    , public.getfunctionddl(p.oid) as DDL
--  , proargtypes, proallargtypes, proargnames, proargmodes, prosrc, ns.nspname, p.proname, prorettype, proacl, prosecdef, rolname, provolatile, proisstrict
--  , p.*
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE lanname <> 'internal';

SELECT * FROM public.getfunctionddl('%' /*schema_name_like*/,'test_func' /*function_name_like*/);
SELECT * FROM public.vw_functionddl;

Другие вопросы по теме