Re: concat_ws - Mailing list pgsql-admin

From Joe Conway
Subject Re: concat_ws
Date
Msg-id 3F2D4B3B.3050405@joeconway.com
Whole thread Raw
In response to Re: concat_ws  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: concat_ws
Re: concat_ws
List pgsql-admin
Tom Lane wrote:
> I think you'd need to generate a separate function definition for
> each number of arguments you wanted to deal with, which is a bit
> of a pain in the neck, but it still beats writing an extension
> function in C ...

I thought I'd whack out this example similar to the GREATEST/LEAST
functions a month or so ago. It works fine in 7.3, but has a problem on
7.4devel. First the function:

create or replace function make_concat_ws() returns text as '
declare
   v_args int := 32;
   v_first text := ''create or replace function
concat_ws(text,text,text) returns text as ''''select case when $1 is
null then null when $3 is null then $2 else $2 || $1 || $3 end''''
language sql IMMUTABLE'';
   v_part1 text := ''create or replace function concat_ws(text,text'';
   v_part2 text := '') returns text as ''''select
concat_ws($1,concat_ws($1,$2'';
   v_part3 text := '')'''' language sql IMMUTABLE'';
   v_sql text;
begin
   execute v_first;
   for i in 4 .. v_args loop
     v_sql := v_part1;
     for j in 3 .. i loop
       v_sql := v_sql || '',text'';
     end loop;

     v_sql := v_sql || v_part2;

     for j in 3 .. i - 1 loop
       v_sql := v_sql || '',$'' || j::text;
     end loop;
     v_sql := v_sql || ''),$'' || i::text;

     v_sql := v_sql || v_part3;
     execute v_sql;
   end loop;
   return ''OK'';
end;
' language 'plpgsql';

select make_concat_ws();

After creating and executing make_concat_ws(), you'll have 30
concat_ws() functions accepting from 3 to 32 arguments. On 7.3 it works
well:

test=# select

concat_ws('~','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31');
                                           concat_ws
----------------------------------------------------------------------------------------------

01~02~03~04~05~06~07~08~09~10~11~12~13~14~15~16~17~18~19~20~21~22~23~24~25~26~27~28~29~30~31
(1 row)

test=# explain analyze select

concat_ws('~','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31');
                                     QUERY PLAN
----------------------------------------------------------------------------------
  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.00..0.00
rows=1 loops=1)
  Total runtime: 0.02 msec
(2 rows)

But on 7.4devel it works OK with smaller numbers of arguments, and seems
to take exponentially longer as arguments are added. The odd thing is
that explain analyze does not seem to reflect this. I noticed that on
7.4devel:

regression=# explain analyze select
concat_ws('~','01','02','03','04','05','06','07','08');
                                                      QUERY PLAN
----------------------------------------------------------------------------------
  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.00..0.00
rows=1 loops=1)
  Total runtime: 0.05 msec
(2 rows)

regression=# explain analyze select
concat_ws('~','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16');
                                     QUERY PLAN
----------------------------------------------------------------------------------
  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.01..0.01
rows=1 loops=1)
  Total runtime: 0.07 msec
(2 rows)

But the "clock" time to run the commands is noticeably longer for the 17
argument case (~2 seconds versus instant). At 25 arguments (possibly
sooner, I didn't test cases in between) it fails with:

regression=# select

concat_ws('~','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24');
ERROR:  ERRORDATA_STACK_SIZE exceeded

I don't have time at the moment to dig into this, but I'll try to later
today or tomorrow.

Joe


pgsql-admin by date:

Previous
From: Tom Lane
Date:
Subject: Re: concat_ws
Next
From: Tom Lane
Date:
Subject: Re: concat_ws