情景#1
基本上,假设我们有一个使用动态 SQL 的函数,但也知道它总是为相同的输入返回相同的输出并声明它是不可变的,它真的是不可变的吗?aka 编译器/查询处理器会知道这种特定情况吗?
根据官方文档
IMMUTABLE 函数不能修改数据库,并且保证在给定相同参数的情况下永远返回相同的结果。此类别允许优化器在查询使用常量参数调用该函数时预先评估该函数。
按照这个逻辑,它应该可以正常工作,因为它只关心输入是否相同。
情景#2
同上,但输入类型为anyelement
or anyarray
。考虑到 SQL 是一种强类型语言(来自官方文档)
SQL 是一种强类型语言。也就是说,每个数据项都有一个关联的数据类型,它决定了它的行为和允许的使用。
并且知道这anyelement
只是一个伪类型,因为实际上在处理函数期间它知道它(例如)是一个整数或字符串。因此,从这个角度来看,一个函数anyelement
在不可变时是否接受并不重要。
我想知道上面写的是否确实是 PostgreSQL 在这些条件下的真实行为。如果与使用常规 SQL 的常规不可变函数相比有什么不同的话。
如果声明了一个函数
IMMUTABLE
,但函数体包含波动较小的函数 (STABLE
,VOLATILE
),则禁用 SQL 函数的函数内联。所以,是的,Postgres 确实关心“里面有什么”。SQL 函数与其他过程语言(如 PL/pgSQL)的函数之间存在差异。动态 SQL 在 SQL 函数中是不可能的。有关的:
但出于许多目的,Postgres 对声明的函数易变性感到满意。例如,如果您构建一个涉及自定义函数的索引,则必须声明它
IMMUTABLE
。信守承诺是您的责任,否则索引将无声无息地崩溃。例子:
多态性(使用
anyelement
等)是一个正交概念。多态函数可以有任何易失性声明。