postgresql 创建concat_ws的不可变克隆

rdrgkggo  于 2023-01-13  发布在  PostgreSQL
关注(0)|答案(2)|浏览(175)

This blog post显示了如何在第页中创建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)、一个胶水(文本或varchar)和一个或多个部分(文本、varchar或空)。
我错过了什么?

iqjalb3h

iqjalb3h1#

    • 首先**,函数在定义中需要 * 两个 * 参数,就像Richard已经建议的那样,您相应地更新了您的问题。
    • 其次**,您可以使用LANGUAGE internal创建具有"any"输入的函数。但这并不意味着您应该这样做。

concat_ws()仅为STABLE是有原因的。其中,datetimestamp的文本表示形式取决于区域设置/日期样式设置,因此结果不是 * 不可变 * 的。基于此生成的索引可能会自动中断。限于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';

在Postgres 9.6或更高版本中将其标记为PARALLEL SAFE(它符合条件!),以便在涉及此函数时启用并行性。
除非另外标记,否则假定所有用户定义函数是并行不安全的。
抵制住做类似immutable_concat_ws('|', now()::text, 'foo')的事情的诱惑,这将在调用中重新引入所述依赖关系。
相关:

  • 合并两列并添加为一个新列
inb24sb2

inb24sb22#

好的,你Map到了内部的C函数,我必须承认我自己从来没有做过。
然而,text_concat_ws是“带分隔符的”,所以它不只是接受文本参数的可变列表-它接受一个分隔符THEN文本参数的可变列表。
如果您打算这样做,您可能希望将调试器挂接到后端,或者在可行的情况下在单个进程中运行它。
还有-我刚刚找到了PostgreSQL源代码的doxygen接口,回答了你的问题。谢谢:-)

相关问题