6

я наткнулся на любопытную функцию подписи в pg_catalog.pg_stat_get_activity:функция PostgreSQL с повторяющимися параметрами

CREATE OR REPLACE FUNCTION pg_stat_get_activity(
    IN pid integer, 
    OUT datid oid, 
    OUT pid integer, 
    -- more parameters...) 
    RETURNS SETOF record AS 'pg_stat_get_activity' 
    LANGUAGE internal STABLE 
    COST 1 
    ROWS 100; 

Эта функция устанавливает такое же имя параметра дважды, также сообщили из information_schema.

select 
    parameter_mode, 
    parameter_name 
from information_schema.parameters 
where specific_schema = 'pg_catalog' 
and specific_name like 'pg_stat_get_activity%' 
order by ordinal_position 

Вышеуказанные выходы (смотри также этот SQLFiddle):

+--------------+----------------+ 
|parameter_mode|parameter_name | 
+--------------+----------------+ 
|IN   |pid    | 
|OUT   |datid   | 
|OUT   |pid    | 
|...   |...    | 
+--------------+----------------+ 

наивности, я попытался создать подобную функцию, без толку:

CREATE FUNCTION f_2647(p1 IN int, p1 OUT int) 
AS $$ 
BEGIN 
    p1 := p1; 
END; 
$$ LANGUAGE plpgsql; 

Мои вопросы:

  1. Почему внутренний pg_stat_get_activity функция redeclare с тем же именем параметра дважды? Какова цель этого? Например. почему бы просто не использовать параметр INOUT?
  2. В чем разница между внутренней функцией pg_stat_get_activity и моей? Почему я не могу использовать этот синтаксис?

Я знаю, что это скорее академические вопросы, но мне нужно, чтобы правильно понять это, чтобы исправить issue в jOOQ CodeGenerator.

+0

Возможно, вы получите более качественные ответы, если вы разместите это в списке рассылки Postgres. –

+0

@a_horse_with_no_name: Обычно переполнение стека не так уж плохо с такими вопросами. Но вы правы, я мог бы перекрестно опубликовать это в конце концов и, если это применимо, обновить этот вопрос. –

+0

Я думал, что, возможно, параметры 'INOUT' могут быть разделены так же, как в системном каталоге, но это не так. У меня нет объяснений. –

ответ

3

Я заметил, что он появился в 9.2. В версии 9.1, то из поля было названо procpid:

 
parameter_mode | parameter_name 
----------------+------------------ 
IN    | pid 
OUT   | datid 
OUT   | procpid 
OUT   | usesysid 
... 

Глядя на изменения в Postgres мерзавец история приводит к этой фиксации:

 
commit 4f42b546fd87a80be30c53a0f2c897acb826ad52 
Author: Magnus Hagander 
Date: Thu Jan 19 14:19:20 2012 +0100 

    Separate state from query string in pg_stat_activity 

    This separates the state (running/idle/idleintransaction etc) into 
    it's own field ("state"), and leaves the query field containing just 
    query text. 

    The query text will now mean "current query" when a query is running 
    and "last query" in other states. Accordingly,the field has been 
    renamed from current_query to query. 

    Since backwards compatibility was broken anyway to make that, the procpid 
    field has also been renamed to pid - along with the same field in 
    pg_stat_replication for consistency. 

    Scott Mead and Magnus Hagander, review work from Greg Smith 

Среди линий, которые изменились, вот один интерес :

 
-DATA(insert OID = 2022 ( pg_stat_get_activity   PGNSP PGUID 12 1 100 0 0 f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,16,1184,1184,1184,869,25,23}" "{i,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,procpid,usesysid,application_name,current_query,waiting,xact_start,query_start,backend_start,client_addr,client_hostname,client_port}" _null_ pg_stat_get_activity _null_ _null_ _null_)); 
+DATA(insert OID = 2022 ( pg_stat_get_activity   PGNSP PGUID 12 1 100 0 0 f f f f t s 1 0 2249 "23" "{23,26,23,26,25,25,25,16,1184,1184,1184,1184,869,25,23}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,waiting,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port}" _null_ pg_stat_get_activity _null_ _null_ _null_)); 

В этом предварительно расщепленный форме, это правдоподобно, что авторы не заметили двойное использование pid, или же они не заботились так как оно на практике безвреден.

Пропущено, потому что эти внутренние функции создаются с помощью initdb по быстрому пути, который пропускает проверку подлинности обычных пользовательских функций.

+0

Интересно, мне не пришло в голову проверить более старые версии PostgreSQL. Спасибо, что посмотрели. –

Смежные вопросы