It's the recurring problem of "SELECT-or-INSERT", closely related to the popular UPSERT problem. The upcoming Postgres 9.5 supplies the new INSERT .. ON CONFLICT DO NOTHING | UPDATE to provide clean solutions for each.
Implementation for Postgres 9.4
For now, I suggest this bullet-proof implementation using two server-side plpgsql functions. Only the helper-function for the INSERT implements the more expensive error-trapping, and that's only called if the SELECT does not succeed.
This never raises an exception due to a unique violation and always returns a row.
Assumptions:
- Assuming a table named - tblwith a column- xof data type- text. Adapt to your case accordingly.
 
- xis defined- UNIQUEor- PRIMARY KEY.
 
- You want to return the whole row from the underlying table (- return a record (found or created)).
 
- In many cases the row is already there. (Does not have to be the majority of cases, - SELECTis a lot cheaper than- INSERT.) Else it may be more efficient to try the- INSERTfirst.
 
Helper function:
CREATE OR REPLACE FUNCTION f_insert_x(_x text)
  RETURNS SETOF tbl AS
$func$
BEGIN
   RETURN QUERY
   INSERT INTO tbl(x) VALUES (_x) RETURNING *;
EXCEPTION WHEN UNIQUE_VIOLATION THEN  -- catch exception, no row is returned
   -- do nothing
END
$func$ LANGUAGE plpgsql;
Main function:
CREATE OR REPLACE FUNCTION f_x(_x text)
  RETURNS SETOF tbl AS
$func$
BEGIN
   LOOP
      RETURN QUERY
      SELECT * FROM tbl WHERE x = _x
      UNION  ALL
      SELECT * FROM f_insert_x(_x)  -- only executed if x not found
      LIMIT  1;
      EXIT WHEN FOUND;       -- else keep looping
   END LOOP;
END
$func$ LANGUAGE plpgsql;
Call:
SELECT * FROM f_x('foo');
SQL Fiddle demo.
The function is based on what I have worked out in this related answer:
Detailed explanation and links there.
We could also create a generic function with polymorphic return type and dynamic SQL to work for any given column and table (but that's beyond the scope of this question):
Basics for UPSERT in this related answer by Craig Ringer: