@jahuuar provided a simple and elegant solution with a single SELECT
to solve this with a single query (also skipping empty strings if you need that). You don't need plpgsql or even a function for this.
While working with plpgsql, you can optimize performance:
CREATE OR REPLACE FUNCTION get_all_companies(_keyword varchar(255))
RETURNS TABLE(id INTEGER, name VARCHAR, isactive boolean) AS
$func$
BEGIN
IF _keyword <> '' THEN -- exclude null and empty string
RETURN QUERY
SELECT c.id, c.name, c.isactive
FROM companydetail AS c
WHERE c.name ~* _keyword
LIMIT 50;
ELSE
RETURN QUERY
SELECT c.id, c.name, c.isactive
FROM companydetail AS c
LIMIT 50;
END IF;
END
$func$ LANGUAGE plpgsql;
Postgres can use separate, optimized plans for the two distinct queries this way. A trigram GIN index scan for the first query (you need the matching index, of course - see links below), a sequential scan for the second. And PL/pgSQL saves query plans when executed repeatedly in the same session.
Related: