【发布时间】:2016-06-08 14:28:30
【问题描述】:
在 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,并且rec_func() 被调用就好像它是@987654334 @。
看起来 PostgreSQL 对 coalesce() 和任何 STRICT 函数使用的 NULL 输入的内部检查与 IS NULL 运算符不同。有什么想法吗?为了解决我的具体问题,当记录输入全部为 NULLs 时,我能做些什么来确保我的函数不会被调用?
最后一点 - 我知道如果条目混合在一起,记录是否为 null 存在一些歧义 - 有些是 NULL,有些不是。但幸运的是我不必处理这种情况,因为我用作输入的表中的所有列都是NOT NULL。所以每当我的函数被调用时,记录要么包含所有空值,要么包含所有非空值。
【问题讨论】:
-
这是个有趣的案例。似乎带有
NULL属性的记录不被视为NULL。唯一想到的是在 plpgsql 中创建一些中间函数来检查NULLs 的记录,然后将其传递给原始函数(在您的示例中传递给rec_func())。
标签: sql postgresql null