Home Explore Blog CI



postgresql

26th chunk of `doc/src/sgml/xfunc.sgml`
c2084d29f98799c767a25752cec604b41873d8f7de0e10c50000000100000fa0
 and just return the
     pointer to the input value.)
    </para>

    <para>
     Finally, all variable-length types must also be  passed
     by  reference.   All  variable-length  types must begin
     with an opaque length field of exactly 4 bytes, which will be set
     by <symbol>SET_VARSIZE</symbol>; never set this field directly! All data to
     be  stored within that type must be located in the memory
     immediately  following  that  length  field.   The
     length field contains the total length of the structure,
     that is,  it  includes  the  size  of  the  length  field
     itself.
    </para>

    <para>
     Another important point is to avoid leaving any uninitialized bits
     within data type values; for example, take care to zero out any
     alignment padding bytes that might be present in structs.  Without
     this, logically-equivalent constants of your data type might be
     seen as unequal by the planner, leading to inefficient (though not
     incorrect) plans.
    </para>

    <warning>
     <para>
      <emphasis>Never</emphasis> modify the contents of a pass-by-reference input
      value.  If you do so you are likely to corrupt on-disk data, since
      the pointer you are given might point directly into a disk buffer.
      The sole exception to this rule is explained in
      <xref linkend="xaggr"/>.
     </para>
    </warning>

    <para>
     As an example, we can define the type <type>text</type> as
     follows:

<programlisting>
typedef struct {
    int32 length;
    char data[FLEXIBLE_ARRAY_MEMBER];
} text;
</programlisting>

     The <literal>[FLEXIBLE_ARRAY_MEMBER]</literal> notation means that the actual
     length of the data part is not specified by this declaration.
    </para>

    <para>
     When manipulating
     variable-length types, we must  be  careful  to  allocate
     the  correct amount  of memory and set the length field correctly.
     For example, if we wanted to  store  40  bytes  in  a <structname>text</structname>
     structure, we might use a code fragment like this:

<programlisting><![CDATA[
#include "postgres.h"
...
char buffer[40]; /* our source data */
...
text *destination = (text *) palloc(VARHDRSZ + 40);
SET_VARSIZE(destination, VARHDRSZ + 40);
memcpy(destination->data, buffer, 40);
...
]]>
</programlisting>

     <literal>VARHDRSZ</literal> is the same as <literal>sizeof(int32)</literal>, but
     it's considered good style to use the macro <literal>VARHDRSZ</literal>
     to refer to the size of the overhead for a variable-length type.
     Also, the length field <emphasis>must</emphasis> be set using the
     <literal>SET_VARSIZE</literal> macro, not by simple assignment.
    </para>

    <para>
     <xref linkend="xfunc-c-type-table"/> shows the C types
     corresponding to many of the built-in SQL data types
     of <productname>PostgreSQL</productname>.
     The <quote>Defined In</quote> column gives the header file that
     needs to be included to get the type definition.  (The actual
     definition might be in a different file that is included by the
     listed file.  It is recommended that users stick to the defined
     interface.)  Note that you should always include
     <filename>postgres.h</filename> first in any source file of server
     code, because it declares a number of things that you will need
     anyway, and because including other headers first can cause
     portability issues.
    </para>

     <table tocentry="1" id="xfunc-c-type-table">
      <title>Equivalent C Types for Built-in SQL Types</title>
      <tgroup cols="3">
       <colspec colname="col1" colwidth="1*"/>
       <colspec colname="col2" colwidth="1*"/>
       <colspec colname="col3" colwidth="2*"/>
       <thead>
        <row>
         <entry>
          SQL Type
         </entry>
         <entry>
          C Type
         </entry>
         <entry>
          Defined In
         </entry>
        </row>
       </thead>
       <tbody>
        <row>
      

Title: Variable-Length Types, Uninitialized Bits, and C Type Equivalents for SQL Types
Summary
Variable-length types must be passed by reference, starting with a 4-byte length field set by SET_VARSIZE. Avoid uninitialized bits within data type values. It's crucial not to modify pass-by-reference input values to prevent data corruption. The 'text' type is demonstrated as an example of a variable-length type with a length field and data. The correct memory allocation and length setting are essential when manipulating these types. VARHDRSZ is equivalent to sizeof(int32) and used to reference the size of the overhead for a variable-length type. The section also references a table of C types corresponding to built-in SQL data types in PostgreSQL, emphasizing the importance of including postgres.h in server code.