I have a Postgres function:
CREATE OR REPLACE FUNCTION get_stats(
_start_date timestamp with time zone,
_stop_date timestamp with time zone,
id_clients integer[],
OUT date timestamp with time zone,
OUT profit,
OUT cost
)
RETURNS SETOF record
LANGUAGE plpgsql
AS $$
DECLARE
query varchar := '';
BEGIN
... -- lot of code
IF id_clients IS NOT NULL THEN
query := query||' AND id = ANY ('||quote_nullable(id_clients)||')';
END IF;
... -- other code
END;
$$;
So if I run query something like this:
SELECT * FROM get_stats('2014-07-01 00:00:00Etc/GMT-3'
, '2014-08-06 23:59:59Etc/GMT-3', '{}');
Generated query has this condition:
"... AND id = ANY('{}')..."
But if an array is empty this condition should not be represented in query.
How can I check if the array of clients is not empty?
I've also tried two variants:
IF ARRAY_UPPER(id_clients) IS NOT NULL THEN
query := query||' AND id = ANY ('||quote_nullable(id_clients)||')';
END IF;
And:
IF ARRAY_LENGTH(id_clients) THEN
query := query||' AND id = ANY ('||quote_nullable(id_clients)||')';
END IF;
In both cases I got this error: ARRAY_UPPER(ARRAY_LENGTH) doesn't exists
;
array_length()
requires two parameters, the second being the dimension of the array:
array_length(id_clients, 1) > 0
So:
IF array_length(id_clients, 1) > 0 THEN
query := query || format(' AND id = ANY(%L))', id_clients);
END IF;
This excludes both empty array and NULL.
Use cardinality()
in Postgres 9.4 or later. See added answer by @bronzenose.
But if you're concatenating a query to run with EXECUTE
, it would be smarter to pass values with a USING
clause. Examples:
To explicitly check whether an array is empty like your title says (but that's not what you need here) just compare it to an empty array:
id_clients = '{}'
That's all. You get:
true
.. array is empty
null
.. array is NULL
false
.. any other case (array has elements - even if just null
elements)