Home Explore Blog CI



postgresql

20th chunk of `doc/src/sgml/xfunc.sgml`
ba9eb537222ea9206fd38a0ad894d8fcbb3ac4a2029303640000000100000fa7
 <literal>IMMUTABLE</literal> function cannot modify the database and is
      guaranteed to return the same results given the same arguments forever.
      This category allows the optimizer to pre-evaluate the function when
      a query calls it with constant arguments.  For example, a query like
      <literal>SELECT ... WHERE x = 2 + 2</literal> can be simplified on sight to
      <literal>SELECT ... WHERE x = 4</literal>, because the function underlying
      the integer addition operator is marked <literal>IMMUTABLE</literal>.
     </para>
    </listitem>
   </itemizedlist>
   </para>

   <para>
    For best optimization results, you should label your functions with the
    strictest volatility category that is valid for them.
   </para>

   <para>
    Any function with side-effects <emphasis>must</emphasis> be labeled
    <literal>VOLATILE</literal>, so that calls to it cannot be optimized away.
    Even a function with no side-effects needs to be labeled
    <literal>VOLATILE</literal> if its value can change within a single query;
    some examples are <literal>random()</literal>, <literal>currval()</literal>,
    <literal>timeofday()</literal>.
   </para>

   <para>
    Another important example is that the <function>current_timestamp</function>
    family of functions qualify as <literal>STABLE</literal>, since their values do
    not change within a transaction.
   </para>

   <para>
    There is relatively little difference between <literal>STABLE</literal> and
    <literal>IMMUTABLE</literal> categories when considering simple interactive
    queries that are planned and immediately executed: it doesn't matter
    a lot whether a function is executed once during planning or once during
    query execution startup.  But there is a big difference if the plan is
    saved and reused later.  Labeling a function <literal>IMMUTABLE</literal> when
    it really isn't might allow it to be prematurely folded to a constant during
    planning, resulting in a stale value being re-used during subsequent uses
    of the plan.  This is a hazard when using prepared statements or when
    using function languages that cache plans (such as
    <application>PL/pgSQL</application>).
   </para>

   <para>
    For functions written in SQL or in any of the standard procedural
    languages, there is a second important property determined by the
    volatility category, namely the visibility of any data changes that have
    been made by the SQL command that is calling the function.  A
    <literal>VOLATILE</literal> function will see such changes, a <literal>STABLE</literal>
    or <literal>IMMUTABLE</literal> function will not.  This behavior is implemented
    using the snapshotting behavior of MVCC (see <xref linkend="mvcc"/>):
    <literal>STABLE</literal> and <literal>IMMUTABLE</literal> functions use a snapshot
    established as of the start of the calling query, whereas
    <literal>VOLATILE</literal> functions obtain a fresh snapshot at the start of
    each query they execute.
   </para>

   <note>
    <para>
     Functions written in C can manage snapshots however they want, but it's
     usually a good idea to make C functions work this way too.
    </para>
   </note>

   <para>
    Because of this snapshotting behavior,
    a function containing only <command>SELECT</command> commands can safely be
    marked <literal>STABLE</literal>, even if it selects from tables that might be
    undergoing modifications by concurrent queries.
    <productname>PostgreSQL</productname> will execute all commands of a
    <literal>STABLE</literal> function using the snapshot established for the
    calling query, and so it will see a fixed view of the database throughout
    that query.
   </para>

   <para>
    The same snapshotting behavior is used for <command>SELECT</command> commands
    within <literal>IMMUTABLE</literal> functions.  It is generally unwise to select
    from database tables within an <literal>IMMUTABLE</literal> function

Title: More on Function Volatility Categories and Snapshotting
Summary
This section expands on the volatility categories (VOLATILE, STABLE, IMMUTABLE) of functions and the impact on query optimization, function behavior, and data visibility. It highlights the need to label functions correctly, especially considering prepared statements and cached plans. It also describes how the volatility category affects the snapshotting behavior of functions in relation to MVCC, determining whether a function sees data changes made by the calling SQL command. Specifically, VOLATILE functions see such changes, while STABLE and IMMUTABLE functions do not. Functions containing only SELECT commands can safely be marked STABLE, even if the tables they query are undergoing modifications, as they will see a fixed view of the database throughout the calling query.