⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xfunc.sgml

📁 PostgreSQL7.4.6 for Linux
💻 SGML
📖 第 1 页 / 共 5 页
字号:
    After it is used for the first time, a dynamically loaded object    file is retained in memory.  Future calls in the same session to    the function(s) in that file will only incur the small overhead of    a symbol table lookup.  If you need to force a reload of an object    file, for example after recompiling it, use the <command>LOAD</>    command or begin a fresh session.   </para>   <para>    It is recommended to locate shared libraries either relative to    <literal>$libdir</literal> or through the dynamic library path.    This simplifies version upgrades if the new installation is at a    different location.  The actual directory that    <literal>$libdir</literal> stands for can be found out with the    command <literal>pg_config --pkglibdir</literal>.   </para>   <para>    Before <productname>PostgreSQL</productname> release 7.2, only    exact absolute paths to object files could be specified in    <command>CREATE FUNCTION</>.  This approach is now deprecated    since it makes the function definition unnecessarily unportable.    It's best to specify just the shared library name with no path nor    extension, and let the search mechanism provide that information    instead.   </para>  </sect2>   <sect2 id="xfunc-c-basetype">    <title>Base Types in C-Language Functions</title>    <indexterm zone="xfunc-c-basetype">     <primary>data type</primary>     <secondary>internal organisation</secondary>    </indexterm>    <para>     To know how to write C-language functions, you need to know how     <productname>PostgreSQL</productname> internally represents base     data types and how they can be passed to and from functions.     Internally, <productname>PostgreSQL</productname> regards a base     type as a <quote>blob of memory</quote>.  The user-defined     functions that you define over a type in turn define the way that     <productname>PostgreSQL</productname> can operate on it.  That     is, <productname>PostgreSQL</productname> will only store and     retrieve the data from disk and use your user-defined functions     to input, process, and output the data.    </para>    <para>     Base types can have one of three internal formats:     <itemizedlist>      <listitem>       <para>	pass by value, fixed-length       </para>      </listitem>      <listitem>       <para>	pass by reference, fixed-length       </para>      </listitem>      <listitem>       <para>	pass by reference, variable-length       </para>      </listitem>     </itemizedlist>    </para>    <para>     By-value  types  can  only be 1, 2, or 4 bytes in length     (also 8 bytes, if <literal>sizeof(Datum)</literal> is 8 on your machine).     You should be careful      to define your types such that  they  will  be  the  same       size (in bytes) on all architectures.  For example, the      <literal>long</literal> type is dangerous because  it       is 4 bytes on some machines and 8 bytes on others, whereas      <type>int</type>  type  is  4  bytes  on  most       Unix machines.  A reasonable implementation of       the  <type>int4</type>  type  on  Unix     machines might be:     <programlisting>/* 4-byte integer, passed by value */typedef int int4;</programlisting>    </para>    <para>     On  the  other hand, fixed-length types of any size may     be passed by-reference.  For example, here is a  sample     implementation of a <productname>PostgreSQL</productname> type:     <programlisting>/* 16-byte structure, passed by reference */typedef struct{    double  x, y;} Point;</programlisting>     Only  pointers  to  such types can be used when passing     them in and out of <productname>PostgreSQL</productname> functions.     To return a value of such a type, allocate the right amount of     memory with <literal>palloc</literal>, fill in the allocated memory,     and return a pointer to it.  (You can also return an input value     that has the same type as the return value directly by returning     the pointer to the input value.  <emphasis>Never</> modify the     contents of a pass-by-reference input value, however.)    </para>    <para>     Finally, all variable-length types must also be  passed     by  reference.   All  variable-length  types must begin     with a length field of exactly 4 bytes, and 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>     As an example, we can define the type <type>text</type> as     follows:<programlisting>typedef struct {    int4 length;    char data[1];} text;</programlisting>     Obviously,  the  data  field declared here is not long enough to hold     all possible strings.  Since it's impossible to declare a variable-size     structure in <acronym>C</acronym>, we rely on the knowledge that the     <acronym>C</acronym> compiler won't range-check array subscripts.  We     just allocate the necessary amount of space and then access the array as     if it were declared the right length.  (This is a common trick, which     you can read about in many textbooks about C.)    </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</>     structure, we might use a code fragment like this:<programlisting>#include "postgres.h"...char buffer[40]; /* our source data */...text *destination = (text *) palloc(VARHDRSZ + 40);destination-&gt;length = VARHDRSZ + 40;memcpy(destination-&gt;data, buffer, 40);...</programlisting>     <literal>VARHDRSZ</> is the same as <literal>sizeof(int4)</>, but     it's considered good style to use the macro <literal>VARHDRSZ</>     to refer to the size of the overhead for a variable-length type.    </para>    <para>     <xref linkend="xfunc-c-type-table"> specifies which C type     corresponds to which SQL type when writing a C-language function     that uses a built-in type of <productname>PostgreSQL</>.     The <quote>Defined In</quote> column gives the header file that     needs to be included to get the type definition.  (The actual     definition may 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, because     it declares a number of things that you will need anyway.    </para>     <table tocentry="1" id="xfunc-c-type-table">      <title>Equivalent C Types for Built-In SQL Types</title>      <tgroup cols="3">       <thead>	<row>	 <entry>	  SQL Type	 </entry>	 <entry>	  C Type	 </entry>	 <entry>	  Defined In	 </entry>	</row>       </thead>       <tbody>	<row>	 <entry><type>abstime</type></entry>	 <entry><type>AbsoluteTime</type></entry>	 <entry><filename>utils/nabstime.h</filename></entry>	</row>	<row>	 <entry><type>boolean</type></entry>	 <entry><type>bool</type></entry>	 <entry><filename>postgres.h</filename> (maybe compiler built-in)</entry>	</row>	<row>	 <entry><type>box</type></entry>	 <entry><type>BOX*</type></entry>	 <entry><filename>utils/geo_decls.h</filename></entry>	</row>	<row>	 <entry><type>bytea</type></entry>	 <entry><type>bytea*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>"char"</type></entry>	 <entry><type>char</type></entry>	 <entry>(compiler built-in)</entry>	</row>	<row>	 <entry><type>character</type></entry>	 <entry><type>BpChar*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>cid</type></entry>	 <entry><type>CommandId</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>date</type></entry>	 <entry><type>DateADT</type></entry>	 <entry><filename>utils/date.h</filename></entry>	</row>	<row>	 <entry><type>smallint</type> (<type>int2</type>)</entry>	 <entry><type>int2</type> or <type>int16</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>int2vector</type></entry>	 <entry><type>int2vector*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>integer</type> (<type>int4</type>)</entry>	 <entry><type>int4</type> or <type>int32</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>real</type> (<type>float4</type>)</entry>	 <entry><type>float4*</type></entry>	<entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>double precision</type> (<type>float8</type>)</entry>	 <entry><type>float8*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>interval</type></entry>	 <entry><type>Interval*</type></entry>	 <entry><filename>utils/timestamp.h</filename></entry>	</row>	<row>	 <entry><type>lseg</type></entry>	 <entry><type>LSEG*</type></entry>	 <entry><filename>utils/geo_decls.h</filename></entry>	</row>	<row>	 <entry><type>name</type></entry>	 <entry><type>Name</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>oid</type></entry>	 <entry><type>Oid</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>oidvector</type></entry>	 <entry><type>oidvector*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>path</type></entry>	 <entry><type>PATH*</type></entry>	 <entry><filename>utils/geo_decls.h</filename></entry>	</row>	<row>	 <entry><type>point</type></entry>	 <entry><type>POINT*</type></entry>	 <entry><filename>utils/geo_decls.h</filename></entry>	</row>	<row>	 <entry><type>regproc</type></entry>	 <entry><type>regproc</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>reltime</type></entry>	 <entry><type>RelativeTime</type></entry>	 <entry><filename>utils/nabstime.h</filename></entry>	</row>	<row>	 <entry><type>text</type></entry>	 <entry><type>text*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>tid</type></entry>	 <entry><type>ItemPointer</type></entry>	 <entry><filename>storage/itemptr.h</filename></entry>	</row>	<row>	 <entry><type>time</type></entry>	 <entry><type>TimeADT</type></entry>	 <entry><filename>utils/date.h</filename></entry>	</row>	<row>	 <entry><type>time with time zone</type></entry>	 <entry><type>TimeTzADT</type></entry>	 <entry><filename>utils/date.h</filename></entry>	</row>	<row>	 <entry><type>timestamp</type></entry>	 <entry><type>Timestamp*</type></entry>	 <entry><filename>utils/timestamp.h</filename></entry>	</row>	<row>	 <entry><type>tinterval</type></entry>	 <entry><type>TimeInterval</type></entry>	 <entry><filename>utils/nabstime.h</filename></entry>	</row>	<row>	 <entry><type>varchar</type></entry>	 <entry><type>VarChar*</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>	<row>	 <entry><type>xid</type></entry>	 <entry><type>TransactionId</type></entry>	 <entry><filename>postgres.h</filename></entry>	</row>       </tbody>      </tgroup>     </table>    <para>     Now that we've gone over all of the possible structures     for base types, we can show some examples of real functions.    </para>   </sect2>   <sect2>    <title>Calling Conventions Version 0 for C-Language Functions</title>    <para>     We present the <quote>old style</quote> calling convention first --- although     this approach is now deprecated, it's easier to get a handle on     initially.  In the version-0 method, the arguments and result     of the C function are just declared in normal C style, but being     careful to use the C representation of each SQL data type as shown     above.    </para>    <para>     Here are some examples:<programlisting>#include "postgres.h"#include &lt;string.h&gt;/* by value */         intadd_one(int arg){    return arg + 1;}/* by reference, fixed length */float8 *add_one_float8(float8 *arg){    float8    *result = (float8 *) palloc(sizeof(float8));    *result = *arg + 1.0;       

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -