Quantcast
Channel: Planet PostgreSQL
Viewing all articles
Browse latest Browse all 9973

Andrew Dunstan: Overloading a variadic function so you can pass zero variadic arguments

$
0
0
This is not a great breakthrough, but I had to wrestle slightly with it yesterday in the context of writing an extension with a variadic Postgres function in C.

In C, you can pass zero variadic arguments to a variadic function like printf(), but Postgres is a bit less forgiving. It requires there to be a value supplied for the variadic array. so you get this happening:
andrew=# create function v1(x text, variadic y int[]) 
returns text language plpgsql as 
$$ begin return x ||y::text; end; $$;
CREATE FUNCTION
andrew=# select v1('a',1,2,3);
    v1    
----------
 a{1,2,3}
(1 row)
andrew=# select v1('a');
ERROR:  function v1(unknown) does not exist
LINE 1: select v1('a');
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Fortunately, Postgres also allows you to supply the variadic parameter explicitly as an array, so we can achieve the wanted effect via overloading:
andrew=# create function v1(text) 
returns text language sql as 
$$ select v1($1,variadic array[]::int[]) $$;
CREATE FUNCTION
andrew=# select v1('a');
 v1  
-----
 a{}
(1 row)

And we can now refine the original function to do something nicer in the zero variadic arguments case:
andrew=# create or replace function v1(x text, variadic y int[]) 
returns text language plpgsql as 
$$ begin return x || case when array_length(y,1) > 0 then y::text else '' end; end; $$;
CREATE FUNCTION
andrew=# select v1('a');
 v1 
----
 a
(1 row)


Viewing all articles
Browse latest Browse all 9973

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>