这篇博文展示了如何在 Pg 中创建
immutable_concat
函数的示例:
CREATE OR REPLACE FUNCTION immutable_concat(VARIADIC "any")
RETURNS text AS 'text_concat'
LANGUAGE internal IMMUTABLE
我想对
concat_ws
做同样的事情,并且相应的 text_concat_ws
确实存在,但是,以下内容只会使进程崩溃:
CREATE OR REPLACE FUNCTION immutable_concat_ws(VARIADIC "any")
RETURNS text AS 'text_concat_ws'
LANGUAGE internal IMMUTABLE
更新:
immutable_concat_ws
的签名应该是(glue, *parts)
,一种胶水(text或varchar)和一个或多个部分(text、varchar或null)。
我在这里缺少什么?
首先,该函数在定义中需要two参数,就像理查德已经建议的那样,并且您相应地更新了您的问题。
其次,您可以使用
"any"
通过 LANGUAGE internal
输入创建该函数。但这并不意味着您应该这样做。
concat_ws()
只是STABLE
是有原因的。其中,date
或timestamp
的文本表示取决于语言环境/日期样式设置,因此结果不是不可变。以此为基础的索引可能会悄然崩溃。仅限于 text
输入,可以安全地声明它 IMMUTABLE
。
由于您只需要 text
输入(或 varchar
,它隐式转换为 text
),因此将其限制为您的用例并确保安全:
CREATE OR REPLACE FUNCTION immutable_concat_ws(text, VARIADIC text[])
RETURNS text
LANGUAGE internal IMMUTABLE PARALLEL SAFE AS
'text_concat_ws';
创建
LANGUAGE internal
函数需要 超级用户 权限。如果这不是一个选择,那么下一个最好的选择就是 SQL 函数,例如:
在 Postgres 9.6 或更高版本中将其标记为
PARALLEL SAFE
(符合条件!),以便在涉及此函数时启用并行性。 说明书:
所有用户定义的函数都被假定为并行不安全,除非另有标记。
抵制做这样的事情的诱惑
immutable_concat_ws('|', now()::text, 'foo')
。这将在调用中重新引入所述依赖项。
相关:
好的,所以你正在映射到内部“C”函数,我必须承认我自己从未这样做过。
但是,
text_concat_ws
是“带有分隔符”,因此它不仅仅采用文本参数的可变参数列表 - 它 采用分隔符然后是文本参数的可变参数列表。相应地调整你的函数定义。
如果您打算这样做,您可能希望将调试器连接到后端或在可行的情况下运行单个进程。另外 - 我刚刚找到了 PostgreSQL 源代码的 doxygen 接口来回答你的问题。谢谢:-)