Erw*_*ter 17 postgresql null stored-procedures plpgsql void
写入PL/pgSQL或SQL可定义为的函数RETURNS void.我最近偶然发现了结果的奇怪差异.
请考虑以下演示:
CREATE OR REPLACE FUNCTION f_sql()
RETURNS void AS
'SELECT NULL::void' -- "do nothing", no special meaning
LANGUAGE sql;
CREATE OR REPLACE FUNCTION f_plpgsql()
RETURNS void AS
$$
BEGIN
NULL; -- "do nothing", no special meaning
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
该函数f_sql()使用唯一可能的方法SELECT(在SQL函数中作为最后一个命令)RETURNS void.我使用它只是因为它是用于此测试目的的最简单方法 - 任何其他函数,例如,UPDATE或者DELETE显示相同的行为.
现在,void是一种虚构的类型.虽然plpgsql功能似乎返回一个空字符串类型相当于void有效,''::void.该sql功能似乎回归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
Run Code Online (Sandbox Code Playgroud)
这可能会产生微妙而混乱的副作用.
差异背后的原因是什么?
Mik*_*ll' 11
(我不是这个源代码的专家.你已经被警告了.)
来源在这里在线.我省略了文件名; 您可以搜索函数名称以查找其定义.我留下了行号(通常),因为它更容易剪切和粘贴,不同的行号意味着源已经改变.
简短的故事是一些"void"返回可能是空的cstrings(空的空终止字符串),而其他的是空指针.
以下是相关的源部分.
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 }
Run Code Online (Sandbox Code Playgroud)
我们还有
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
Run Code Online (Sandbox Code Playgroud)
因此,对我来说,通过PG_RETURN_VOID()返回的用户定义函数不会测试等效于通过void_out()或void_send()返回的函数.我还不知道为什么会这样,但我必须停下来睡一会儿.
| 归档时间: |
|
| 查看次数: |
13757 次 |
| 最近记录: |