Prohibit DML queries in function bodies
See original GitHub issueThe proposal is to prohibit INSERT
, UPDATE
, and DELETE
statements in function bodies.
Currently these statements cannot appear in conditional expressions. More specifically, they are executed unconditionally, so it is semantically misleading to place them in a conditional branch that may or may not be executed - so this is forbidden. There’s a specialized form of these statements that allows them to be conditionally executed #1639.
However, functions don’t have the same unconditional execution policy and if these statements were to appear in functions, this could lead to unpredictable results, especially since function calls may be optimized by the query planner based on volatility and where they appear. In order to prevent unspecified behavior we currently choose to ban data manipulation inside function bodies.
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (11 by maintainers)
I would even say that we need a statement like
CALL create_new_session()
orMUTATE WITH create_new_session()
and this is the only place where these functions can be used. Then these functions are as apparent asINSERT
/UPDATE
/DELETE
statements and can be used in a same way (i.e. not a part of conditionals, …etc)The simplest functions are pure, deterministic, do not access the database and always terminate normally. On top of that there are a bunch of additional capabilities a function could have:
Functions used in constraints cannot access to database and not determinism is generally a bad idea in constraints.
Functions mutating cannot be optimized out and can only be used in certain places.
IMO you should encode at least enough of the above properties in the function to decide if the function can be used in constraints or conditionals.
The minimal design which achieves that would be three types of function:
function
(pure, deterministic, can throw exceptions and run forever. Can be used in constraints and conditionals.query
can also read from the database and be read external state/be non deterministic. Can not be used in constraints but can be used in conditionals.mutation
can also write to the database and external state. Can neither be used in constraints nor in conditionals.