I want to decide whether to hide some of the fields based on the value of the field:
CREATE FUNCTION hide(messages) RETURNS messages AS
$$
SELECT CASE
WHEN $1.is_public THEN $1 -- modify only if "is_public" is false
ELSE ROW (
$1.id,
$1.name, -- some other
E'\\x00000000', -- hide this
'', -- hide this
'[]', -- hide this
$1.created,
$1.modified,
)::messages END AS result;
$$ LANGUAGE SQL;
It works, but the maintainability is poor. Every time I change the messages table I have to change this function at the same time.
Is there a better way?
I assume your problem is having to keep adding public fields into the function if they are added to messages. You might have a little more flexibility at the cost of some speed with
CREATE FUNCTION hide(messages) RETURNS messages AS
$$
DECLARE
retval messages;
BEGIN
IF $1.is_public THEN
retval = $1; -- copy
SELECT 0, '', '[]' INTO retval.private_field1,
retval.private_field2, retval.private_field3;
RETURN retval;
ELSE RETURN $1;
END IF;
END
$$ LANGUAGE PLPGSQL;