6

で奇妙な関数シグネチャを見つけましたpg_catalog.pg_stat_get_activity:

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;

この関数は同じパラメータ名を 2 回宣言していますが、これは からも報告されてい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内部関数が同じパラメーター名を 2 回再宣言するのはなぜですか? これの目的は何ですか?たとえば、なぜINOUTパラメーターを使用しないのですか?
  2. pg_stat_get_activity内部関数と私の違いは何ですか?この構文を使用できないのはなぜですか?

これらはかなりアカデミックな質問であることは承知していますが、jOOQ codegenerator の問題を修正するには、これを正しく理解する必要があります。

4

1 に答える 1

3

9.2で登場したことに気づきました。バージョン 9.1 では、out フィールドの名前はprocpid次のようになりました。

パラメータモード | パラメータ名  
----------------+--------------------------------
 に | ピッド
 アウト | 日付
 アウト | しつこい
 アウト | usesysid
 ...

postgres git 履歴の変更を探すと、次のコミットにつながります。

コミット 4f42b546fd87a80be30c53a0f2c897acb826ad52
作者: マグナス・ハガンダー
日付: 2012 年 1 月 19 日 (木) 14:19:20 +0100

    pg_stat_activity で状態をクエリ文字列から分離

    これにより、状態 (running/idle/idleintransaction など) が次のように分離されます。
    それは独自のフィールド(「状態」)であり、クエリフィールドには
    クエリ テキスト。

    クエリの実行中に、クエリ テキストが「現在のクエリ」を意味するようになりました
    および他の状態の「最後のクエリ」。したがって、フィールドはされています
    current_query から query に名前が変更されました。

    とにかく下位互換性が壊れていたので、procpid
    field も pid に名前が変更されました - の同じフィールドとともに
    一貫性のための pg_stat_replication。

    Scott Mead と Magnus Hagander、Greg Smith の作品のレビュー

変更された行の中で、興味深いのは次のとおりです。

-DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 ffffts 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 ffffts 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、通常のユーザー関数の作成チェックをスキップする高速パスで作成されるため、許可されます。

于 2013-09-20T20:30:16.280 に答える