PostgreSQL has an attribute
LEAKRPOOF which you can use to declare a function,
LEAKPROOFindicates that the function has no side effects. It reveals no information about its arguments other than by its return value. For example, a function which throws an error message for some argument values but not others, or which includes the argument values in any error message, is not leakproof. This affects how the system executes queries against views created with the
security_barrieroption or tables with row level security enabled. The system will enforce conditions from security policies and security barrier views before any user-supplied conditions from the query itself that contain non-leakproof functions, in order to prevent the inadvertent exposure of data. Functions and operators marked as leakproof are assumed to be trustworthy, and may be executed before conditions from security policies and security barrier views.
The query planner has more flexibility when dealing with functions that have no side effects. Such functions are referred to as
LEAKPROOF, and include many simple, commonly used operators, such as many equality operators. The query planner can safely allow such functions to be evaluated at any point in the query execution process, since invoking them on rows invisible to the user will not leak any information about the unseen rows. Further, functions which do not take arguments or which are not passed any arguments from the security barrier view do not have to be marked as
LEAKPROOFto be pushed down, as they never receive data from the view. In contrast, a function that might throw an error depending on the values received as arguments (such as one that throws an error in the event of overflow or division by zero) is not leak-proof, and could provide significant information about the unseen rows if applied before the security view's row filters.
Is the following
CREATE FUNCTION foo_leakproof(bar int) RETURNS int AS $$ SELECT bar; $$ IMMUTABLE LEAKPROOF LANGUAGE sql;
Ever planned differently or does it run with a different runtime profile than the
LEAKPROOF lacking alternative,
CREATE FUNCTION foo_leaky(bar int) RETURNS int AS $$ SELECT bar; $$ IMMUTABLE LANGUAGE sql;