加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PostgreSQL函数返回void

发布时间:2020-12-13 16:26:43 所属栏目:百科 来源:网络整理
导读:以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 FUNC
以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;

函数f_sql()在RETURNS无效的SQL函数中使用唯一可能的方式作为SELECT(作为最后一个命令).我使用它只是因为它是测试目的的最简单的方法 – 任何其他功能,例如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

这可能会有微妙和混乱的副作用.
差异背后的原因是什么?

(我不是这个源代码的专家,你已经被警告了.)

来源是在线here.我省略了文件名;您可以搜索该功能
名字找到他们的定义.我离开行号(通常),因为它更容易剪切和粘贴,不同的行号将意味着源已经改变.

简短的故事是,一些“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 }

我们还有

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()返回的函数.我还不知道为什么,但我必须停下来睡觉.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读