创建 concat_ws 的不可变克隆

Create an immutable clone of concat_ws

This blog post 显示了如何在 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)。

我在这里错过了什么?

好的,所以你正在映射到内部 "C" 函数,我必须承认我自己从未这样做过。

但是,text_concat_ws 是 "with separator",因此它不仅采用可变文本参数列表 - 它 takes a separator THEN the variadic list of text 参数。相应地调整您的函数定义。

如果您要这样做,您可能希望将调试器连接到后端,或者 运行 如果可行的话,它是单个进程。

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

First,函数在定义中需要 two 参数,就像 Richard 已经建议的那样,你相应地更新了你的问题。

Second,您可以使用 LANGUAGE internal 输入 "any" 创建该函数。但这并不意味着你应该这样做。

concat_ws() 只是 STABLE 是有原因的。其中,datetimestamp 的文本表示取决于语言环境/日期样式设置,因此结果并非 不变 。以此为基础的索引可能会悄无声息地崩溃。限于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 以在涉及此函数时不破坏并行性。 The manual:

all user-defined functions are assumed to be parallel unsafe unless otherwise marked.

抵制这样的诱惑immutable_concat_ws('|', now()::text, 'foo')。这将在调用中重新引入所述依赖关系。

相关:

  • Combine two columns and add into one new column