【问题标题】:Postgresql STRICT function with null record input argument具有空记录输入参数的 Postgresql STRICT 函数
【发布时间】: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


【解决方案1】:

当您调用带有record 参数的STRICT 函数时,会在行级别进行检查:行是作为参数传递还是NULL?不检查该行的内容。解决方法是在函数开始时检查记录中任何字段的值,如果是NULL,则检查RETURN NULL,否则处理函数的其余部分。

【讨论】:

  • 所以参数检查和IS NULL不一样?因为在包含所有 NULL 条目的记录的情况下,rec IS NULL 将评估为 TRUE...?
【解决方案2】:

在传递记录时,使用nullif 转为显式null

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

【讨论】:

  • 正如我在问题开头所说的,我使用的实际函数是在 C 中,而不是 sql...
猜你喜欢
  • 2014-03-24
  • 2015-04-10
  • 2013-09-26
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 2019-02-14
  • 2017-10-05
  • 2018-08-19
相关资源
最近更新 更多