一連のテキストを返す 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 record
1 つのout
パラメーターと両方のパラメーターを持つ関数を定義することはできません。代わりに、出力タイプは常にテーブルとして (または同様の方法で) 定義する必要があります。
誰でも私を修正してもらえますか?これが本当だとしたら、本当に迷惑です。きっと私はどこかで間違いを犯しましたか?