创建 concat_ws 的不可变克隆

问题描述 投票:0回答:2

这篇博文展示了如何在 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)。

我在这里缺少什么?

postgresql function concatenation concat-ws
2个回答
14
投票

首先,该函数在定义中需要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')
。这将在调用中重新引入所述依赖项。

相关:


1
投票

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

但是,

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.