最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

postgresql - Create an immutable version of CONCAT() - Stack Overflow

programmeradmin3浏览0评论

I tried to create an immutable CONCAT(). For this, I tried to use the following SQL queries.

Option 1

CREATE FUNCTION immutable_concat(VARIADIC text[])
  RETURNS text
  LANGUAGE internal IMMUTABLE PARALLEL SAFE AS 'text_concat';

Option 2

CREATE FUNCTION immutable_concat(VARIADIC text[])
  RETURNS text
  LANGUAGE sql IMMUTABLE PARALLEL SAFE
  RETURN array_to_string($1, '');

As a result, I get a function that works well with text. But how can I create a similar function that will take an array containing not only text elements?

CONCAT() allows us to execute the following SQL query:

SELECT concat(CURRENT_DATE, true, false, 1, 'text');

As a result, we will get the following string:

2025-03-07tf1text

Ideally, I would like to create a function that can take different elements. I mean the following:

SELECT immutable_concat(CURRENT_DATE, true, false, 1, 'text');

I tried to create an immutable CONCAT(). For this, I tried to use the following SQL queries.

Option 1

CREATE FUNCTION immutable_concat(VARIADIC text[])
  RETURNS text
  LANGUAGE internal IMMUTABLE PARALLEL SAFE AS 'text_concat';

Option 2

CREATE FUNCTION immutable_concat(VARIADIC text[])
  RETURNS text
  LANGUAGE sql IMMUTABLE PARALLEL SAFE
  RETURN array_to_string($1, '');

As a result, I get a function that works well with text. But how can I create a similar function that will take an array containing not only text elements?

CONCAT() allows us to execute the following SQL query:

SELECT concat(CURRENT_DATE, true, false, 1, 'text');

As a result, we will get the following string:

2025-03-07tf1text

Ideally, I would like to create a function that can take different elements. I mean the following:

SELECT immutable_concat(CURRENT_DATE, true, false, 1, 'text');
Share Improve this question edited Mar 7 at 16:24 Ivan Yuzafatau asked Mar 7 at 15:01 Ivan YuzafatauIvan Yuzafatau 7545 silver badges19 bronze badges 1
  • As long as element types match and you quote the function body, you can use a polymorphic anyarray. – Zegarek Commented Mar 7 at 15:16
Add a comment  | 

1 Answer 1

Reset to default 2

The way concat() can do that is by accepting variadic any which neither sql nor plpgsql language functions are allowed to. As long as element types match and you quote the function body, you can use a polymorphic anyarray:
demo at db<>fiddle

CREATE FUNCTION immutable_concat(VARIADIC anyarray)
  RETURNS text
  LANGUAGE sql IMMUTABLE PARALLEL SAFE
  as $$ select array_to_string($1, '') $$;

select immutable_concat(1,2,3)
      ,immutable_concat(true,false,false)
      ,immutable_concat(1e2,.1,9.)
      ,immutable_concat(now(),'infinity','today allballs');
immutable_concat immutable_concat immutable_concat immutable_concat
123 tff 1000.19 2025-03-07 15:20:26.448193+00infinity2025-03-07 00:00:00+00

You can also reclassify the internal concat():

CREATE FUNCTION immutable_concat(VARIADIC "any")
  RETURNS text
  LANGUAGE internal IMMUTABLE PARALLEL SAFE
  as 'text_concat';
select immutable_concat(1,'x'::text,false);
immutable_concat
1xf

My guess is you're trying to use that for a generated expression or a functional index and if so, I'm assuming you know the risk.

发布评论

评论列表(0)

  1. 暂无评论