gpt4 book ai didi

PostgreSQL 函数返回 void

转载 作者:行者123 更新时间:2023-11-29 11:10:50 40 4
gpt4 key购买 nike

PL/pgSQLSQL 编写的函数可以定义为RETURNS void。我最近偶然发现了一个奇怪的结果差异。

考虑以下演示:

CREATE OR REPLACE FUNCTION f_sql()
RETURNS void
LANGUAGE sql AS
'SELECT NULL::void'; -- = "do nothing", no special meaning


CREATE OR REPLACE FUNCTION f_plpgsql()
RETURNS void
LANGUAGE plpgsql AS
$func$
BEGIN
NULL; -- = "do nothing", no special meaning
END;
$func$;

f_sql() 函数在 RETURNS void。我使用它只是因为它是用于此测试目的的最简单方法 - 任何其他函数,例如 UPDATEDELETE,都会显示相同的行为。

现在,void 是一个虚构的类型。虽然 plpgsql 函数似乎返回一个空字符串的等价物作为类型 void - 实际上是 ''::voidsql 函数似乎返回 NULL::void

db=# SELECT f_sql() IS NULL;
?column?
----------
t

db=# SELECT f_sql()::text IS NULL;
?column?
----------
t

db=# SELECT f_plpgsql() IS NULL;
?column?
----------
f

db=# SELECT f_plpgsql()::text = '';
?column?
----------
t

这可能会产生微妙且令人困惑的副作用。
差异背后的原因是什么?

最佳答案

(我不是这个源代码的专家。你已经被警告过。)

来源在线here .我省略了文件名;你可以搜索功能名称以找到它们的定义。我(通常)保留了行号,因为它更容易剪切和粘贴,不同的行号意味着源已更改。

简而言之,一些“void”返回可能是空 cstring(空的以 null 结尾的字符串),而其他则是空指针。

以下是来源中看起来相关的部分。

00228 /*
00229 * void_out - output routine for pseudo-type VOID.
00230 *
00231 * We allow this so that "SELECT function_returning_void(...)" works.
00232 */
00233 Datum
00234 void_out(PG_FUNCTION_ARGS)
00235 {
00236 PG_RETURN_CSTRING(pstrdup(""));
00237 }

00251 /*
00252 * void_send - binary output routine for pseudo-type VOID.
00253 *
00254 * We allow this so that "SELECT function_returning_void(...)" works
00255 * even when binary output is requested.
00256 */
00257 Datum
00258 void_send(PG_FUNCTION_ARGS)
00259 {
00260 StringInfoData buf;
00261
00262 /* send an empty string */
00263 pq_begintypsend(&buf);
00264 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00265 }

我们还有

00285 /* To return a NULL do this: */
00286 #define PG_RETURN_NULL() \
00287 do { fcinfo->isnull = true; return (Datum) 0; } while (0)
00288
00289 /* A few internal functions return void (which is not the same as NULL!) */
00290 #define PG_RETURN_VOID() return (Datum) 0

因此对我来说,通过 PG_RETURN_VOID() 返回的用户定义函数不会测试等同于通过 void_out() 或 void_send() 返回的函数。我还不知道为什么会这样,但我必须停下来睡会儿觉。

关于PostgreSQL 函数返回 void,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8319986/

40 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com