mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Further polishing of documentation about new fmgr call convention.
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
				
			|||||||
<!--
 | 
					<!--
 | 
				
			||||||
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.30 2001/01/22 16:11:17 tgl Exp $
 | 
					$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.31 2001/02/15 19:03:35 tgl Exp $
 | 
				
			||||||
-->
 | 
					-->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 <chapter id="xfunc">
 | 
					 <chapter id="xfunc">
 | 
				
			||||||
@@ -434,10 +434,9 @@ SELECT clean_EMP();
 | 
				
			|||||||
     functions that will be loaded into Postgres.  The "Defined In"
 | 
					     functions that will be loaded into Postgres.  The "Defined In"
 | 
				
			||||||
     column gives the actual header file (in the
 | 
					     column gives the actual header file (in the
 | 
				
			||||||
     <filename>.../src/backend/</filename>
 | 
					     <filename>.../src/backend/</filename>
 | 
				
			||||||
     directory) that the equivalent C type is defined.  However, if you
 | 
					     directory) that the equivalent C type is defined.  Note that you should
 | 
				
			||||||
     include <filename>utils/builtins.h</filename>,
 | 
					     always include <filename>postgres.h</filename> first, and that in turn
 | 
				
			||||||
     these files will automatically be
 | 
					     includes <filename>c.h</filename>.
 | 
				
			||||||
     included.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
     <table tocentry="1">
 | 
					     <table tocentry="1">
 | 
				
			||||||
      <title>Equivalent C Types
 | 
					      <title>Equivalent C Types
 | 
				
			||||||
@@ -619,9 +618,8 @@ SELECT clean_EMP();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <para>
 | 
					    <para>
 | 
				
			||||||
     By-value  types  can  only be 1, 2 or 4 bytes in length
 | 
					     By-value  types  can  only be 1, 2 or 4 bytes in length
 | 
				
			||||||
     (even if your computer supports by-value types of other
 | 
					     (also 8 bytes, if sizeof(Datum) is 8 on your machine).
 | 
				
			||||||
     sizes).   <productname>Postgres</productname>  itself 
 | 
					     You should be careful 
 | 
				
			||||||
     only passes integer types by value.  You should be careful 
 | 
					 | 
				
			||||||
     to define your types such that  they  will  be  the  same  
 | 
					     to define your types such that  they  will  be  the  same  
 | 
				
			||||||
     size (in bytes) on all architectures.  For example, the 
 | 
					     size (in bytes) on all architectures.  For example, the 
 | 
				
			||||||
     <literal>long</literal> type is dangerous because  it  
 | 
					     <literal>long</literal> type is dangerous because  it  
 | 
				
			||||||
@@ -657,7 +655,9 @@ typedef struct
 | 
				
			|||||||
     them in and out of <productname>Postgres</productname> functions.
 | 
					     them in and out of <productname>Postgres</productname> functions.
 | 
				
			||||||
     To return a value of such a type, allocate the right amount of
 | 
					     To return a value of such a type, allocate the right amount of
 | 
				
			||||||
     memory with <literal>palloc()</literal>, fill in the allocated memory,
 | 
					     memory with <literal>palloc()</literal>, fill in the allocated memory,
 | 
				
			||||||
     and return a pointer to it.
 | 
					     and return a pointer to it.  (Alternatively, you can return an input
 | 
				
			||||||
 | 
					     value of the same type by returning its pointer.  <emphasis>Never</>
 | 
				
			||||||
 | 
					     modify the contents of a pass-by-reference input value, however.)
 | 
				
			||||||
    </para>
 | 
					    </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <para>
 | 
					    <para>
 | 
				
			||||||
@@ -721,8 +721,8 @@ memmove(destination->data, buffer, 40);
 | 
				
			|||||||
     Here are some examples:
 | 
					     Here are some examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<programlisting>
 | 
					<programlisting>
 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include "postgres.h"
 | 
					#include "postgres.h"
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* By Value */
 | 
					/* By Value */
 | 
				
			||||||
         
 | 
					         
 | 
				
			||||||
@@ -780,10 +780,10 @@ concat_text(text *arg1, text *arg2)
 | 
				
			|||||||
    int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
 | 
					    int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
 | 
				
			||||||
    text *new_text = (text *) palloc(new_text_size);
 | 
					    text *new_text = (text *) palloc(new_text_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset((void *) new_text, 0, new_text_size);
 | 
					 | 
				
			||||||
    VARATT_SIZEP(new_text) = new_text_size;
 | 
					    VARATT_SIZEP(new_text) = new_text_size;
 | 
				
			||||||
    strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
 | 
					    memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
 | 
				
			||||||
    strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
 | 
					    memcpy(VARDATA(new_text) + (VARSIZE(arg1)-VARHDRSZ),
 | 
				
			||||||
 | 
					           VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
 | 
				
			||||||
    return new_text;
 | 
					    return new_text;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</programlisting>
 | 
					</programlisting>
 | 
				
			||||||
@@ -882,8 +882,8 @@ PG_FUNCTION_INFO_V1(funcname);
 | 
				
			|||||||
     Here we show the same functions as above, coded in version-1 style:
 | 
					     Here we show the same functions as above, coded in version-1 style:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<programlisting>
 | 
					<programlisting>
 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include "postgres.h"
 | 
					#include "postgres.h"
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
#include "fmgr.h"
 | 
					#include "fmgr.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* By Value */
 | 
					/* By Value */
 | 
				
			||||||
@@ -959,10 +959,10 @@ concat_text(PG_FUNCTION_ARGS)
 | 
				
			|||||||
    int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
 | 
					    int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
 | 
				
			||||||
    text *new_text = (text *) palloc(new_text_size);
 | 
					    text *new_text = (text *) palloc(new_text_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset((void *) new_text, 0, new_text_size);
 | 
					 | 
				
			||||||
    VARATT_SIZEP(new_text) = new_text_size;
 | 
					    VARATT_SIZEP(new_text) = new_text_size;
 | 
				
			||||||
    strncpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
 | 
					    memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1)-VARHDRSZ);
 | 
				
			||||||
    strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
 | 
					    memcpy(VARDATA(new_text) + (VARSIZE(arg1)-VARHDRSZ),
 | 
				
			||||||
 | 
					           VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
 | 
				
			||||||
    PG_RETURN_TEXT_P(new_text);
 | 
					    PG_RETURN_TEXT_P(new_text);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</programlisting>
 | 
					</programlisting>
 | 
				
			||||||
@@ -991,10 +991,20 @@ concat_text(PG_FUNCTION_ARGS)
 | 
				
			|||||||
    </para>
 | 
					    </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <para>
 | 
					    <para>
 | 
				
			||||||
     The version-1 function call conventions also make it possible to
 | 
					     One big improvement in version-1 functions is better handling of NULL
 | 
				
			||||||
     test for NULL inputs to a non-strict function, return a NULL
 | 
					     inputs and results.  The macro <function>PG_ARGISNULL(n)</function>
 | 
				
			||||||
     result (from either strict or non-strict functions), return
 | 
					     allows a function to test whether each input is NULL (of course, doing
 | 
				
			||||||
     <quote>set</quote> results, and implement trigger functions and
 | 
					     this is only necessary in functions not declared <quote>strict</>).
 | 
				
			||||||
 | 
					     As with the
 | 
				
			||||||
 | 
					     <function>PG_GETARG_<replaceable>xxx</replaceable>()</function> macros,
 | 
				
			||||||
 | 
					     the input arguments are counted beginning at zero.
 | 
				
			||||||
 | 
					     To return a NULL result, execute <function>PG_RETURN_NULL()</function>;
 | 
				
			||||||
 | 
					     this works in both strict and non-strict functions.
 | 
				
			||||||
 | 
					    </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <para>
 | 
				
			||||||
 | 
					     The version-1 function call conventions make it possible to
 | 
				
			||||||
 | 
					     return <quote>set</quote> results and implement trigger functions and
 | 
				
			||||||
     procedural-language call handlers.  Version-1 code is also more
 | 
					     procedural-language call handlers.  Version-1 code is also more
 | 
				
			||||||
     portable than version-0, because it does not break ANSI C restrictions
 | 
					     portable than version-0, because it does not break ANSI C restrictions
 | 
				
			||||||
     on function call protocol.  For more details see
 | 
					     on function call protocol.  For more details see
 | 
				
			||||||
@@ -1167,11 +1177,14 @@ LANGUAGE 'c';
 | 
				
			|||||||
      <listitem>
 | 
					      <listitem>
 | 
				
			||||||
       <para>
 | 
					       <para>
 | 
				
			||||||
        Most of the internal <productname>Postgres</productname> types
 | 
					        Most of the internal <productname>Postgres</productname> types
 | 
				
			||||||
	are declared in <filename>postgres.h</filename>, the function
 | 
						are declared in <filename>postgres.h</filename>, while the function
 | 
				
			||||||
	manager interfaces (<symbol>PG_FUNCTION_ARGS</symbol>, etc.)
 | 
						manager interfaces (<symbol>PG_FUNCTION_ARGS</symbol>, etc.)
 | 
				
			||||||
	are in <filename>fmgr.h</filename>, so you will need to
 | 
						are in <filename>fmgr.h</filename>, so you will need to
 | 
				
			||||||
	include at least these two files.  Including
 | 
						include at least these two files.  For portability reasons it's best
 | 
				
			||||||
	<filename>postgres.h</filename> will also include
 | 
						to include <filename>postgres.h</filename> <emphasis>first</>,
 | 
				
			||||||
 | 
						before any other system or user header files.
 | 
				
			||||||
 | 
						Including <filename>postgres.h</filename> will also include
 | 
				
			||||||
 | 
						<filename>c.h</filename>,
 | 
				
			||||||
	<filename>elog.h</filename> and <filename>palloc.h</filename>
 | 
						<filename>elog.h</filename> and <filename>palloc.h</filename>
 | 
				
			||||||
	for you.
 | 
						for you.
 | 
				
			||||||
       </para>
 | 
					       </para>
 | 
				
			||||||
@@ -1210,7 +1223,7 @@ LANGUAGE 'c';
 | 
				
			|||||||
   <title>Function Overloading</title>
 | 
					   <title>Function Overloading</title>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    More than one function may be defined with the same name, as long as
 | 
					    More than one function may be defined with the same name, so long as
 | 
				
			||||||
    the arguments they take are different.  In other words, function names
 | 
					    the arguments they take are different.  In other words, function names
 | 
				
			||||||
    can be <firstterm>overloaded</firstterm>.
 | 
					    can be <firstterm>overloaded</firstterm>.
 | 
				
			||||||
    A function may also have the same name as an attribute.  In the case
 | 
					    A function may also have the same name as an attribute.  In the case
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user