Home Explore Blog CI



postgresql

51th chunk of `doc/src/sgml/xfunc.sgml`
38951d985c3a586d033214a7e5d029e6c54613173ee2579e0000000100000fa5
 example describing how to register and use custom statistics can be
     found in <filename>src/test/modules/injection_points</filename>.
    </para>
   </sect2>

   <sect2 id="extend-cpp">
    <title>Using C++ for Extensibility</title>

    <indexterm zone="extend-cpp">
     <primary>C++</primary>
    </indexterm>

    <para>
     Although the <productname>PostgreSQL</productname> backend is written in
     C, it is possible to write extensions in C++ if these guidelines are
     followed:

     <itemizedlist>
      <listitem>
       <para>
         All functions accessed by the backend must present a C interface
         to the backend;  these C functions can then call C++ functions.
         For example, <literal>extern C</literal> linkage is required for
         backend-accessed functions.  This is also necessary for any
         functions that are passed as pointers between the backend and
         C++ code.
       </para>
      </listitem>
      <listitem>
       <para>
        Free memory using the appropriate deallocation method.  For example,
        most backend memory is allocated using <function>palloc()</function>, so use
        <function>pfree()</function> to free it.  Using C++
        <function>delete</function> in such cases will fail.
       </para>
      </listitem>
      <listitem>
       <para>
        Prevent exceptions from propagating into the C code (use a catch-all
        block at the top level of all <literal>extern C</literal> functions).  This
        is necessary even if the C++ code does not explicitly throw any
        exceptions, because events like out-of-memory can still throw
        exceptions.  Any exceptions must be caught and appropriate errors
        passed back to the C interface.  If possible, compile C++ with
        <option>-fno-exceptions</option> to eliminate exceptions entirely; in such
        cases, you must check for failures in your C++ code, e.g.,  check for
        NULL returned by <function>new()</function>.
       </para>
      </listitem>
      <listitem>
       <para>
        If calling backend functions from C++ code, be sure that the
        C++ call stack contains only plain old data structures
        (<acronym>POD</acronym>).  This is necessary because backend errors
        generate a distant <function>longjmp()</function> that does not properly
        unroll a C++ call stack with non-POD objects.
       </para>
      </listitem>
     </itemizedlist>
    </para>

    <para>
     In summary, it is best to place C++ code behind a wall of
     <literal>extern C</literal> functions that interface to the backend,
     and avoid exception, memory, and call stack leakage.
    </para>
   </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 <link linkend="sql-createfunction"><command>CREATE FUNCTION</command></link> 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

Title: Using C++ for PostgreSQL Extensibility and Function Optimization
Summary
This section outlines guidelines for using C++ to write PostgreSQL extensions, emphasizing the need for a C interface for backend functions, proper memory management using palloc/pfree, preventing exceptions from propagating into C code, and ensuring the C++ call stack contains only POD structures. It also introduces function optimization information, highlighting how declarative annotations in CREATE FUNCTION, like volatility and parallel safety, can improve query execution efficiency.