diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 6 | ||||
-rw-r--r-- | doc/src/sgml/keywords.sgml | 7 | ||||
-rw-r--r-- | doc/src/sgml/ref/alter_function.sgml | 19 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_function.sgml | 14 | ||||
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 120 | ||||
-rw-r--r-- | doc/src/sgml/xoper.sgml | 12 |
6 files changed, 141 insertions, 37 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index af4d0625eab..6dd0700da75 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -5146,11 +5146,11 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l </row> <row> - <entry><structfield>protransform</structfield></entry> + <entry><structfield>prosupport</structfield></entry> <entry><type>regproc</type></entry> <entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry> - <entry>Calls to this function can be simplified by this other function - (see <xref linkend="xfunc-transform-functions"/>)</entry> + <entry>Optional planner support function for this function + (see <xref linkend="xfunc-optimization"/>)</entry> </row> <row> diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml index a37d0b756bd..fa32a88b8e2 100644 --- a/doc/src/sgml/keywords.sgml +++ b/doc/src/sgml/keywords.sgml @@ -4522,6 +4522,13 @@ <entry>reserved</entry> </row> <row> + <entry><token>SUPPORT</token></entry> + <entry>non-reserved</entry> + <entry></entry> + <entry></entry> + <entry></entry> + </row> + <row> <entry><token>SYMMETRIC</token></entry> <entry>reserved</entry> <entry>reserved</entry> diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml index d8747e07482..03ffa5945a2 100644 --- a/doc/src/sgml/ref/alter_function.sgml +++ b/doc/src/sgml/ref/alter_function.sgml @@ -40,6 +40,7 @@ ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="param PARALLEL { UNSAFE | RESTRICTED | SAFE } COST <replaceable class="parameter">execution_cost</replaceable> ROWS <replaceable class="parameter">result_rows</replaceable> + SUPPORT <replaceable class="parameter">support_function</replaceable> SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT } SET <replaceable class="parameter">configuration_parameter</replaceable> FROM CURRENT RESET <replaceable class="parameter">configuration_parameter</replaceable> @@ -248,6 +249,24 @@ ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="param </listitem> </varlistentry> + <varlistentry> + <term><literal>SUPPORT</literal> <replaceable class="parameter">support_function</replaceable></term> + + <listitem> + <para> + Set or change the planner support function to use for this function. + See <xref linkend="xfunc-optimization"/> for details. You must be + superuser to use this option. + </para> + + <para> + This option cannot be used to remove the support function altogether, + since it must name a new support function. Use <command>CREATE OR + REPLACE FUNCTION</command> if you need to do that. + </para> + </listitem> + </varlistentry> + <varlistentry> <term><replaceable>configuration_parameter</replaceable></term> <term><replaceable>value</replaceable></term> diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index 40725431842..dd6a2f73049 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -33,6 +33,7 @@ CREATE [ OR REPLACE ] FUNCTION | PARALLEL { UNSAFE | RESTRICTED | SAFE } | COST <replaceable class="parameter">execution_cost</replaceable> | ROWS <replaceable class="parameter">result_rows</replaceable> + | SUPPORT <replaceable class="parameter">support_function</replaceable> | SET <replaceable class="parameter">configuration_parameter</replaceable> { TO <replaceable class="parameter">value</replaceable> | = <replaceable class="parameter">value</replaceable> | FROM CURRENT } | AS '<replaceable class="parameter">definition</replaceable>' | AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>' @@ -478,6 +479,19 @@ CREATE [ OR REPLACE ] FUNCTION </varlistentry> <varlistentry> + <term><literal>SUPPORT</literal> <replaceable class="parameter">support_function</replaceable></term> + + <listitem> + <para> + The name (optionally schema-qualified) of a <firstterm>planner support + function</firstterm> to use for this function. See + <xref linkend="xfunc-optimization"/> for details. + You must be superuser to use this option. + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><replaceable>configuration_parameter</replaceable></term> <term><replaceable>value</replaceable></term> <listitem> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index e18272c33a1..d70aa6eed78 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3241,40 +3241,6 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray </para> </sect2> - <sect2 id="xfunc-transform-functions"> - <title>Transform Functions</title> - - <para> - Some function calls can be simplified during planning based on - properties specific to the function. For example, - <literal>int4mul(n, 1)</literal> could be simplified to just <literal>n</literal>. - To define such function-specific optimizations, write a - <firstterm>transform function</firstterm> and place its OID in the - <structfield>protransform</structfield> field of the primary function's - <structname>pg_proc</structname> entry. The transform function must have the SQL - signature <literal>protransform(internal) RETURNS internal</literal>. The - argument, actually <type>FuncExpr *</type>, is a dummy node representing a - call to the primary function. If the transform function's study of the - expression tree proves that a simplified expression tree can substitute - for all possible concrete calls represented thereby, build and return - that simplified expression. Otherwise, return a <literal>NULL</literal> - pointer (<emphasis>not</emphasis> a SQL null). - </para> - - <para> - We make no guarantee that <productname>PostgreSQL</productname> will never call the - primary function in cases that the transform function could simplify. - Ensure rigorous equivalence between the simplified expression and an - actual call to the primary function. - </para> - - <para> - Currently, this facility is not exposed to users at the SQL level - because of security concerns, so it is only practical to use for - optimizing built-in functions. - </para> - </sect2> - <sect2> <title>Shared Memory and LWLocks</title> @@ -3388,3 +3354,89 @@ if (!ptr) </sect2> </sect1> + + <sect1 id="xfunc-optimization"> + <title>Function Optimization Information</title> + + <indexterm zone="xfunc-optimization"> + <primary>optimization information</primary> + <secondary>for functions</secondary> + </indexterm> + + <para> + By default, a function is just a <quote>black box</quote> that the + database system knows very little about the behavior of. However, + that means that queries using the function may be executed much less + efficiently than they could be. It is possible to supply additional + knowledge that helps the planner optimize function calls. + </para> + + <para> + Some basic facts can be supplied by declarative annotations provided in + the <xref linkend="sql-createfunction"/> command. Most important of + these is the function's <link linkend="xfunc-volatility">volatility + category</link> (<literal>IMMUTABLE</literal>, <literal>STABLE</literal>, + or <literal>VOLATILE</literal>); one should always be careful to + specify this correctly when defining a function. + The parallel safety property (<literal>PARALLEL + UNSAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or + <literal>PARALLEL SAFE</literal>) 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. + </para> + + <para> + It is also possible to attach a <firstterm>planner support + function</firstterm> to a SQL-callable function (called + its <firstterm>target function</firstterm>), 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. + </para> + + <para> + A planner support function must have the SQL signature +<programlisting> +supportfn(internal) returns internal +</programlisting> + It is attached to its target function by specifying + the <literal>SUPPORT</literal> clause when creating the target function. + </para> + + <para> + The details of the API for planner support functions can be found in + file <filename>src/include/nodes/supportnodes.h</filename> in the + <productname>PostgreSQL</productname> 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. + </para> + + <para> + Some function calls can be simplified during planning based on + properties specific to the function. For example, + <literal>int4mul(n, 1)</literal> could be simplified to + just <literal>n</literal>. This type of transformation can be + performed by a planner support function, by having it implement + the <literal>SupportRequestSimplify</literal> 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, <literal>n * 1</literal> would also be simplified to + <literal>n</literal>. + (But note that this is just an example; this particular + optimization is not actually performed by + standard <productname>PostgreSQL</productname>.) + We make no guarantee that <productname>PostgreSQL</productname> 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. + </para> + </sect1> diff --git a/doc/src/sgml/xoper.sgml b/doc/src/sgml/xoper.sgml index 2f5560ac505..260e43c6459 100644 --- a/doc/src/sgml/xoper.sgml +++ b/doc/src/sgml/xoper.sgml @@ -78,6 +78,11 @@ SELECT (a + b) AS c FROM test_complex; <sect1 id="xoper-optimization"> <title>Operator Optimization Information</title> + <indexterm zone="xoper-optimization"> + <primary>optimization information</primary> + <secondary>for operators</secondary> + </indexterm> + <para> A <productname>PostgreSQL</productname> operator definition can include several optional clauses that tell the system useful things about how @@ -97,6 +102,13 @@ SELECT (a + b) AS c FROM test_complex; the ones that release &version; understands. </para> + <para> + It is also possible to attach a planner support function to the function + that underlies an operator, providing another way of telling the system + about the behavior of the operator. + See <xref linkend="xfunc-optimization"/> for more information. + </para> + <sect2> <title><literal>COMMUTATOR</literal></title> |