7

This blog post shows an example of how to create a immutable_concat function in Pg:

CREATE OR REPLACE FUNCTION immutable_concat(VARIADIC "any")
  RETURNS text AS 'text_concat'
  LANGUAGE internal IMMUTABLE

I'd like to do the same with concat_ws and the corresponding text_concat_ws does exist, however, the following just crashes the process:

CREATE OR REPLACE FUNCTION immutable_concat_ws(VARIADIC "any")
  RETURNS text AS 'text_concat_ws'
  LANGUAGE internal IMMUTABLE

Update: The siguature of immutable_concat_ws should be (glue, *parts), one glue (text or varchar) and one or more parts (text, varchar or null).

What am I missing here?

4

2 回答 2

8

首先,该函数在定义中需要两个参数,就像 Richard 已经建议的那样,您相应地更新了您的问题。

其次,您可以"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 AS 'text_concat_ws' LANGUAGE internal IMMUTABLE PARALLEL SAFE;

将其标记为PARALLEL SAFE在涉及此功能时不会破坏并行性。手册:

除非另有标记,否则所有用户定义的函数都假定为并行不安全的。

抵制做这种事情的诱惑immutable_concat_ws('|', now()::text, 'foo')。这将在调用中重新引入所述依赖项。

有关的:

于 2019-01-27T03:15:33.943 回答
1

好的,所以你正在映射到内部“C”函数,我必须承认我自己从来没有做过。

但是,text_concat_ws是“带分隔符”,因此它不仅采用文本参数的可变参数列表 - 它采用分隔符 THEN 文本参数的可变参数列表。相应地调整您的函数定义。

如果您要这样做,您可能希望将调试器连接到后端或在可行的情况下运行单个进程。

另外 - 我刚刚找到了 PostgreSQL 源代码的 doxygen 接口来回答你的问题。谢谢 :-)

于 2019-01-25T21:19:29.587 回答