我想在 PostgreSQL 中编写一个 plpython3u 函数,它返回一组文本。我偶然发现了一个对我来说很奇怪的难题。根据手册,我可以执行以下操作:
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)
现在我们来到有趣的部分。从上面概括,下面的一个或多个公式应该是正确的:要返回一组单个值,要么返回 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 参数。由于我的 SQL 解析器不查看 Python 函数内部,这让我怀疑——</p>
在 PostgreSQL 中,不可能定义一个同时returns setof record
具有单个out
参数的函数;相反,输出类型必须始终定义为表(或通过类似方式)。
谁能纠正我?如果事实证明这是真的,那将真的很烦人。我肯定在某个地方犯了错误吗?