web-dev-qa-db-ja.com

PostgreSQLのドキュメントをナビゲートして、特定のタイプで機能するすべての関数のリストを見つけるにはどうすればよいですか?

jsonbで動作できる関数 のリストを見つけたいとしましょう。ターミナルなしでこれを行う最も効果的な方法は何ですか? googleを使用していますか?アクセスのみを想定

  • マニュアルページ
  • psql
  • postgresqlテーブル
1
Evan Carroll

いくつかの方法がありますが、3つすべてに対処してみましょう。

マニュアルページ

これらの質問に対処するmanページはありません。 PostgreSQLのドキュメントはたくさんありますが、現在そのようなものはなく、PostgreSQLのperldocもありません。これをカバーするドキュメントはHTMLとしてのみ配布されます-ターミナルブラウザ(elinks、lynx、w3mなど)で引き続き表示できます。ほとんどのディストリビューションはこれを個別にパッケージ化しますが、Ubuntuではこれを行います。

_Sudo apt-get install postgresql-doc
elinks /usr/share/doc/postgres*/html/index.html
_

psql

これにPSQLを使用するには、_\dfS_を使用する必要があります。 _\?_ですべてのpsqlコマンドのリストを見ることができます。 _\dfS_を実行した後、タイプを検索するだけです。 _\dfS_が端末幅でラップするビューアを使用している場合、 `\ setenvを使用して設定することで、ラップしないように指示できます。ほとんどのポケットベルは環境変数で引数を受け入れるため、ラップせずにLESSを使用できます。

_\setenv PAGER less
\setenv LESS -S
_

これらはすべて、psqlの_man page_に埋め込まれています。シェル内のpsqlヘルプの_\?_の出力のほとんどは、そのマニュアルページでも詳しく説明されています。たとえば、これは_\?_が示すものです。

_\df[antw][S+] [PATRN]  list [only agg/normal/trigger/window] functions
_

そして、これは_man psql_が示すものです。

関数を、引数、戻り値の型、および関数の型とともに一覧表示します。これらは、「agg」(集計)、「normal」、「trigger」、または「window」に分類されます。特定のタイプの関数のみを表示するには、対応する文字a、n、t、またはwをコマンドに追加します。 patternを指定すると、名前がpatternに一致する関数のみが表示されます。デフォルトでは、ユーザーが作成したオブジェクトのみが表示されます。システムオブジェクトを含めるためのパターンまたはS修飾子を指定します。\df +の形式を使用すると、セキュリティ分類、ボラティリティ、所有者、言語、ソースコード、説明など、各機能に関する追加情報が表示されます。

ヒント引数を取る関数または特定のタイプの値を返す関数を検索するには、ページャーの検索機能を使用して\ df出力をスクロールします。

PostgreSQLカタログ

まず、クエリするwhatのアイデアが必要です。それは複雑なパーティーです。上記では、_\dfS_を使用していることがわかっているので、次のようにpsqlで開始点を取得できます。

_psql -E -c"\dfS" -d myDB | less -S
_

これは、クエリから始まります。

_********* QUERY **********
SELECT n.nspname as "Schema",
  p.proname as "Name",
  pg_catalog.pg_get_function_result(p.oid) as "Result data type",
  pg_catalog.pg_get_function_arguments(p.oid) as "Argument data types",
 CASE
  WHEN p.proisagg THEN 'agg'
  WHEN p.proiswindow THEN 'window'
  WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger'
  ELSE 'normal'
 END as "Type"
FROM pg_catalog.pg_proc p
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE pg_catalog.pg_function_is_visible(p.oid)
ORDER BY 1, 2, 4;
**************************
_

これで、_p.proname as "Name"_とpg_catalog.pg_get_function_arguments(p.oid) as "Argument data types"を組み合わせて、必要なものだけを表示する_\dfS_の簡略版を取得できます。

_SELECT p.proname AS "Name",
  pg_get_function_arguments(p.oid) AS "Argument data types"
FROM pg_proc AS p
WHERE pg_get_function_arguments(p.oid) like '%jsonb%';
_

pg_proc についてもう少し調べてみると、

proargtypes-oidvector-pg_type.oid-関数引数のデータ型を含む配列。これには、入力引数(INOUT引数とVARIADIC引数を含む)のみが含まれるため、関数の呼び出しシグネチャを表します。

これにより、oidを介して_pg_type_に対して非常に具体的なクエリを実行できるようになります。

_SELECT proname AS "Name"
FROM pg_proc
  INNER JOIN pg_type ON ( pg_type.oid = ANY(proargtypes) )
WHERE typname = 'jsonb';
_

そして、それはまさに私たちが望むものを私たちにもたらします。

information_schema

ここでは当てはまらないかもしれませんが、一般的に言えば、_information_schema_にいくつかの情報があります。この汎用インターフェースはすべてをサポートしているわけではなく、低速であり、psqlは内部でそれを使用しません。この情報は_information_schema.routines_にはまったく表示されませんでした。

この回答の一部は、恥知らずに この質問 から発想を得ましたが、より友好的なリソースを目指していました。

2
Evan Carroll

関数のリストを見つけたいjsonbで機能する

あなたの答え これまでのところ見つけるだけです:

  • 関数シグニチャに1つ以上のjsonbパラメータを持つ関数。

良いスタートですが、あなたが求めているもののサブセットにすぎません。

オブジェクト識別子タイプ を使用して、クエリを簡略化および改善できます。

SELECT oid::regprocedure AS func_with_params, prorettype::regtype AS return_type
FROM   pg_proc
WHERE  'jsonb'::regtype = ANY(proargtypes);

このクエリを理解することは、次のことを検討し始めるための最小要件です。

WITH RECURSIVE cte AS (
   SELECT 'jsonb'::regtype AS my_type

   UNION      -- fold dupes
   SELECT a.attrelid::regclass::text::regtype
   FROM   cte t
   JOIN   pg_attribute a ON a.atttypid = t.my_type
   )
SELECT p.oid::regprocedure AS func, prorettype::regtype AS return_type
FROM   pg_proc p 
WHERE  EXISTS (
   SELECT 1
   FROM   cte 
   WHERE  my_type = ANY (proargtypes)
   OR     my_type = prorettype
   )
ORDER  BY 1;

これには、より多くの関数が含まれますjsonbで機能します:

  • containsjsonb列の複合/行タイプをとる関数。
  • 型は再帰的にネストできるため、最後のポイントは再帰的に解決する必要があります。
  • 関数returningjsonb
  • 関数returning上記のタイプのいずれか含むjsonb

ネストされたタイプをテストするには:

CREATE TEMP TABLE j2(t text, j jsonb);
CREATE TEMP TABLE j22(j j2);
CREATE TEMP TABLE j222(j j22);

CREATE FUNCTION pg_temp.f_j() RETURNS jsonb AS 'SELECT NULL::jsonb' LANGUAGE sql;
CREATE FUNCTION pg_temp.f_j2(j2) RETURNS bool AS 'SELECT true' LANGUAGE sql;
CREATE FUNCTION pg_temp.f_j222(j222) RETURNS bool AS 'SELECT true' LANGUAGE sql;

そして、上記のクエリを再度実行します。

もっと

そして、私たちはまだこれらについて話していません:

  • 多態性関数(さまざまなデータ型で呼び出すことができます)。

  • 本体でjsonbを処理するが、jsonbを取得も返却もしない関数。たとえば、PL/pgSQL関数は、関数本体が文字列に格納され、セッションの最初の呼び出しで解析および計画されるため、システムテーブルに依存関係を格納しません。

  • 暗黙的または割り当てのキャストと関数タイプの解決。

    問題のデータ型は、暗黙的な型キャストの後、他の関数への有効な入力である可能性があります。

  • ドメイン、型付きテーブル、おそらく他のエキゾチックな機能。

1