From: | Joe Conway <mail(at)joeconway(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | Hans Spaans <pgsql-admin(at)lists(dot)hansspaans(dot)nl>, pgsql-admin(at)postgresql(dot)org |
Subject: | Re: concat_ws |
Date: | 2003-08-03 17:49:47 |
Message-ID: | 3F2D4B3B.3050405@joeconway.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-admin pgsql-hackers |
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
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2003-08-03 18:14:34 | Re: concat_ws |
Previous Message | Tom Lane | 2003-08-03 15:55:35 | Re: concat_ws |
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2003-08-03 18:14:34 | Re: concat_ws |
Previous Message | Tom Lane | 2003-08-03 16:03:46 | Re: SQL2003 GENERATED ... AS ... syntax |