diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 04bf919b3438..3055f32f1375 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -4090,107 +4090,173 @@ extern PgStat_Kind pgstat_register_kind(PgStat_Kind kind, knowledge that helps the planner optimize function calls. - - Some basic facts can be supplied by declarative annotations provided in - the CREATE FUNCTION command. Most important of - these is the function's volatility - category (IMMUTABLE, STABLE, - or VOLATILE); one should always be careful to - specify this correctly when defining a function. - The parallel safety property (PARALLEL - UNSAFE, PARALLEL RESTRICTED, or - PARALLEL SAFE) must also be specified if you hope - to use the function in parallelized queries. - It can also be useful to specify the function's estimated execution - cost, and/or the number of rows a set-returning function is estimated - to return. However, the declarative way of specifying those two - facts only allows specifying a constant value, which is often - inadequate. - + + Function Inlining + + function + inlining + - - It is also possible to attach a planner support - function to an SQL-callable function (called - its target function), and thereby provide - knowledge about the target function that is too complex to be - represented declaratively. Planner support functions have to be - written in C (although their target functions might not be), so this is - an advanced feature that relatively few people will use. - + + Even with no extra information, the planner may be able to inline the function + into the calling query. The rules vary depending on whether the function returns + a single result or is a set-returning function. + But in all cases the function must be implemented in SQL (not PL/pgSQL). + It must not be SECURITY DEFINER. + And if an extension has hooked function entry/exit, + then inlining must be skipped. + + + + For single-result functions, the function body must be a single + SELECT expression statement + returning a single column. + It must not return a RECORD. + It must return a type that matches the function declaration. + It cannot recurse. It must not include CTEs, a FROM clause, + references to tables or table-like objects, DISTINCT, + GROUP BY, HAVING, + aggregate functions, window functions, + ORDER BY, LIMIT, OFFSET, + UNION, INTERSECT, or EXCEPT. + Its arguments, if used more than once in its body, cannot include VOLATILE functions. + The hypothetical inlined expression must be no more volatile than the original function + (so an IMMUTABLE function must inline to an IMMUTABLE + expression, and a STABLE function must inline to STABLE or IMMUTABLE). + If the original function was STRICT, then any called functions must be STRICT. + For more control, see SupportRequestSimplify. + + + + For set-returning functions, inlining lets the planner merge the query into the + outer query, enabling optimizations like qual pushdown, constant folding, etc. + The function body must be a single SELECT statement. + It must be declared STABLE or IMMUTABLE. + It must not be STRICT. + In addition its arguments may not include volatile function calls or + sub-queries. The function must be called from the FROM clause, + not the SELECT clause, nor with ORDINALITY or + ROWS FROM. + + - - A planner support function must have the SQL signature + + Function Annotations + + function + annotations + + + + Some basic facts can be supplied by declarative annotations provided in + the CREATE FUNCTION command. Most important of + these is the function's volatility + category (IMMUTABLE, STABLE, + or VOLATILE); one should always be careful to + specify this correctly when defining a function. + The parallel safety property (PARALLEL + UNSAFE, PARALLEL RESTRICTED, or + PARALLEL SAFE) must also be specified if you hope + to use the function in parallelized queries. + It can also be useful to specify the function's estimated execution + cost, and/or the number of rows a set-returning function is estimated + to return. However, the declarative way of specifying those two + facts only allows specifying a constant value, which is often + inadequate. + + + + + Function Support Functions + + function + support functions + + + + It is also possible to attach a planner support + function to an SQL-callable function (called + its target function), and thereby provide + knowledge about the target function that is too complex to be + represented declaratively. Planner support functions have to be + written in C (although their target functions might not be), so this is + an advanced feature that relatively few people will use. + + + + A planner support function must have the SQL signature supportfn(internal) returns internal - It is attached to its target function by specifying - the SUPPORT clause when creating the target function. - + It is attached to its target function by specifying + the SUPPORT clause when creating the target function. + - - The details of the API for planner support functions can be found in - file src/include/nodes/supportnodes.h in the - PostgreSQL source code. Here we provide - just an overview of what planner support functions can do. - The set of possible requests to a support function is extensible, - so more things might be possible in future versions. - + + The details of the API for planner support functions can be found in + file src/include/nodes/supportnodes.h in the + PostgreSQL source code. Here we provide + just an overview of what planner support functions can do. + The set of possible requests to a support function is extensible, + so more things might be possible in future versions. + - - Some function calls can be simplified during planning based on - properties specific to the function. For example, - int4mul(n, 1) could be simplified to - just n. This type of transformation can be - performed by a planner support function, by having it implement - the SupportRequestSimplify request type. - The support function will be called for each instance of its target - function found in a query parse tree. If it finds that the particular - call can be simplified into some other form, it can build and return a - parse tree representing that expression. This will automatically work - for operators based on the function, too — in the example just - given, n * 1 would also be simplified to - n. - (But note that this is just an example; this particular - optimization is not actually performed by - standard PostgreSQL.) - We make no guarantee that PostgreSQL will - never call the target function in cases that the support function could - simplify. Ensure rigorous equivalence between the simplified - expression and an actual execution of the target function. - + + Some function calls can be simplified during planning based on + properties specific to the function. For example, + int4mul(n, 1) could be simplified to + just n. This type of transformation can be + performed by a planner support function, by having it implement + the SupportRequestSimplify request type. + The support function will be called for each instance of its target + function found in a query parse tree. If it finds that the particular + call can be simplified into some other form, it can build and return a + parse tree representing that expression. This will automatically work + for operators based on the function, too — in the example just + given, n * 1 would also be simplified to + n. + (But note that this is just an example; this particular + optimization is not actually performed by + standard PostgreSQL.) + We make no guarantee that PostgreSQL will + never call the target function in cases that the support function could + simplify. Ensure rigorous equivalence between the simplified + expression and an actual execution of the target function. + - - For target functions that return boolean, it is often useful to estimate - the fraction of rows that will be selected by a WHERE clause using that - function. This can be done by a support function that implements - the SupportRequestSelectivity request type. - + + For target functions that return boolean, it is often useful to estimate + the fraction of rows that will be selected by a WHERE clause using that + function. This can be done by a support function that implements + the SupportRequestSelectivity request type. + - - If the target function's run time is highly dependent on its inputs, - it may be useful to provide a non-constant cost estimate for it. - This can be done by a support function that implements - the SupportRequestCost request type. - + + If the target function's run time is highly dependent on its inputs, + it may be useful to provide a non-constant cost estimate for it. + This can be done by a support function that implements + the SupportRequestCost request type. + - - For target functions that return sets, it is often useful to provide - a non-constant estimate for the number of rows that will be returned. - This can be done by a support function that implements - the SupportRequestRows request type. - + + For target functions that return sets, it is often useful to provide + a non-constant estimate for the number of rows that will be returned. + This can be done by a support function that implements + the SupportRequestRows request type. + - - For target functions that return boolean, it may be possible to - convert a function call appearing in WHERE into an indexable operator - clause or clauses. The converted clauses might be exactly equivalent - to the function's condition, or they could be somewhat weaker (that is, - they might accept some values that the function condition does not). - In the latter case the index condition is said to - be lossy; it can still be used to scan an index, - but the function call will have to be executed for each row returned by - the index to see if it really passes the WHERE condition or not. - To create such conditions, the support function must implement - the SupportRequestIndexCondition request type. - + + For target functions that return boolean, it may be possible to + convert a function call appearing in WHERE into an indexable operator + clause or clauses. The converted clauses might be exactly equivalent + to the function's condition, or they could be somewhat weaker (that is, + they might accept some values that the function condition does not). + In the latter case the index condition is said to + be lossy; it can still be used to scan an index, + but the function call will have to be executed for each row returned by + the index to see if it really passes the WHERE condition or not. + To create such conditions, the support function must implement + the SupportRequestIndexCondition request type. + +