1

一連のテキストを返す plpython3u 関数を PostgreSQL で作成したいと考えています。私には奇妙に見える難問に出くわしました。マニュアルに従って、次のことができます。

drop schema if exists X cascade;
create schema X;

create type X.greeting AS (
  who text
  );

create function X.greet( how text )
  returns setof X.greeting language plpython3u as $$
  for who in [ 'World', 'PostgreSQL', 'PL/Python' ]:
    yield ( who, )
  $$;

これは、単一のテキストを含む一連の行を返す Python 関数です。非常に多くのことが機能し、期待される出力が得られます。

select X.greet( 'helo' );

    greet     
--------------
 (World)
 (PostgreSQL)
 (PL/Python)
(3 rows)

select * from X.greet( 'helo' );

    who     
------------
 World
 PostgreSQL
 PL/Python
(3 rows)

ここまでは順調ですね。ただし、この目的のためにテーブル定義を記述したくありません。setof record代わりに、この例のように使用したいと思います (たまたま整数を使用していますが、それでも):

create function X.pairs_of_integers_A( out integer, out integer )
  returns setof record language plpython3u as $$
  return [ ( 12, 24, ), ( 36, 48, ), ( 60, 72, ) ]
  $$;

create function X.pairs_of_integers_B( out integer, out integer )
  returns setof record language plpython3u as $$
  for pair in [ ( 12, 24, ), ( 36, 48, ), ( 60, 72, ) ]:
    yield pair
  $$;

select * from X.pairs_of_integers_A();
select * from X.pairs_of_integers_B();

 column1 | column2 
---------+---------
      12 |      24
      36 |      48
      60 |      72
(3 rows)

 column1 | column2 
---------+---------
      12 |      24
      36 |      48
      60 |      72
(3 rows)

ここで、興味深い部分に進みます。上記から一般化すると、以下の 1 つ以上の定式化が正しいはずです: 単一値のセットを返すには、Python タプルのリスト、Python 数値のリストを返すか、単一値のタプルまたは単一値のいずれかを反復します。値:

create function X.single_integers_A( out integer )
  returns setof record language plpython3u as $$
  return [ ( 12, ), ( 36, ), ( 60, ), ]
  $$;

create function X.single_integers_B( out integer )
  returns setof record language plpython3u as $$
  return [ 12, 36, 60, ]
  $$;

create function X.single_integers_C( out integer )
  returns setof record language plpython3u as $$
  for n in [ ( 12, ), ( 36, ), ( 60, ), ]
    yield n
  $$;

create function X.single_integers_D( out integer )
  returns setof record language plpython3u as $$
  for n in [ 12, 36, 60, ]
    yield n
  $$;

コンパイルしても上記のどれも判明しません。それらはすべて SQL パーサーが OUT パラメータのために function result type must be integer でスローアップする原因となります。SQL パーサーは Python 関数の内部を調べないため、次のことが疑われます—</p>

PostgreSQL では、returns setof record1 つのoutパラメーターと両方のパラメーターを持つ関数を定義することはできません。代わりに、出力タイプは常にテーブルとして (または同様の方法で) 定義する必要があります

誰でも私を修正してもらえますか?これが本当だとしたら、本当に迷惑です。きっと私はどこかで間違いを犯しましたか?

4

1 に答える 1