具有空记录输入参数的Postgresql STRICT函数

时间:2016-02-25 17:01:54

标签: sql postgresql null

在PostgreSQL 9.4中,我有一个接受记录(表条目)作为输入参数的函数。函数是STRICT,所以我希望如果输入是空记录(例如(NULL,NULL,NULL)),则不会调用该函数,我会得到NULL输出。这是期望的行为,因为我的函数计算成本很高。

但PostgreSQL似乎认为在决定是否调用该函数时,空记录确实不为空,并且无论如何都要调用我的昂贵函数,从而导致垃圾输出。请注意,该函数是用C编写的,我没有费心处理NULL输入,因为我使用了STRICT关键字。

这是一个用来说明问题的小例子:

create table test_table as
  select null::int as a, null::int as b;

create function rec_func(test_table) returns text as
$$
  select 'Function got called'::text;
$$
language sql strict;

select t, t is null as is_null, coalesce(t,(1,2)::test_table), rec_func(t)
from test_table t;

选择查询的输出:

t           is_null  coalesce    rec_func
test_table  boolean  test_table  text
----------  -------  ----------  -------------------
(,)         t        (,)         Function got called

根据IS NULL运算符,输入记录(,)确实是NULL,但coalesce()返回(,),就好像它不是null和{{ 1}}被调用,好像它是rec_func()

not nullNULL函数使用的coalesce()输入的PostgreSQL内部检查与STRICT运算符不同。有什么想法发生了什么?为了解决我的具体问题,当记录输入全部为IS NULL时,我该怎样做才能确保我的函数不被调用?

最后一点 - 我明白如果条目是混合的,那么记录是否为空有一些含糊不清 - 有些NULL,有些不是。NULL。但幸运的是,我不必处理这种情况,因为我用作输入的表中的所有列都是NOT NULL。因此,无论何时调用我的函数,记录都包含所有空值或所有非空值。

2 个答案:

答案 0 :(得分:0)

当您使用public function stopAction($campaignId) { return new Response('Process Stoped'); } 参数调用A函数时,会在行的级别进行检查:是作为参数传递的行还是STRICT?不检查行的内容。解决方案是你应该检查函数开头记录中任何字段的值,record if NULL,否则处理函数的其余部分。

答案 1 :(得分:0)

转过来使用nullif来传递记录时显示null

select rec_func(nullif(test_table, (null,null)::test_table))
from test_table