SELECT COALESCE( (SELECT value FROM precomputed WHERE ...),alwaysComputeValue(...) );
第二个表达式会被评估吗?
这还取决于执行计划员还是独立的?
Like a CASE expression,COALESCE only evaluates the arguments that are needed to determine the result; that is,arguments to the right of the first non-null argument are not evaluated.
https://www.postgresql.org/docs/9.6/static/functions-conditional.html
但是,如果右边的表达式不是volatile,那么它是否是懒惰的应该没有区别,所以在这种情况下,如果查询计划程序稳定或者是正常的,那么它将是允许的.不可变的,如果这似乎是一个明智的优化.
一个明显的例子是,使用SELECT COALESCE(a,b)FROM表,它可能会检索所有行的a和b字段,而不是检索a然后在必要时检索b.
关于在这里产生任何可观察效果的唯一方法是,如果你编写了一个易失性函数,并故意将其错误标记为稳定或不可变.然后,如果在左侧不为空的合并的右侧,则可以对其进行评估. (当然,一个功能确实很稳定,但如果它稳定,它就没有副作用,如果没有副作用,它是否发生是不可观察的).
鉴于:
CREATE OR REPLACE FUNCTION immutable_func(arg integer) RETURNS integer AS $BODY$ BEGIN RAISE NOTICE 'Immutable function called with %',arg; RETURN arg; END; $BODY$LANGUAGE plpgsql IMMUTABLE; WITH data AS ( SELECT 10 AS num UNION ALL SELECT 5 UNION ALL SELECT 20 ) select coalesce(num,immutable_func(2)) from data
规划器知道它对每行都有相同的immutable_func(2)结果,并为整个查询调用一次,给我们用2调用的消息Immutable函数.所以它确实已被评估,即使它不是在“第一个非空参数的权利的参数未被评估”的规则内.回报是在多个零数的(合理预期)情况下,它仍然只运行一次.
这是违反记录行为的信件是好的,因为我们已经告诉它这样的优化是有效的.如果这导致了问题,那么错误就是将功能标记为IMMUTABLE,而不是在急切的评估中.
它也可以是部分方式.使用SELECT COALESCE(a,Some_Func(b))FROM表,它不会急切地评估Some_Func(b),但它将检索b以便能够这样做.
任何时候它实际上影响(非作弊)可观察行为,遵循规则.