mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +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 */
|
||||||
@ -945,7 +945,7 @@ copytext(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
memcpy((void *) VARDATA(new_t), /* destination */
|
memcpy((void *) VARDATA(new_t), /* destination */
|
||||||
(void *) VARDATA(t), /* source */
|
(void *) VARDATA(t), /* source */
|
||||||
VARSIZE(t)-VARHDRSZ); /* how many bytes */
|
VARSIZE(t)-VARHDRSZ); /* how many bytes */
|
||||||
PG_RETURN_TEXT_P(new_t);
|
PG_RETURN_TEXT_P(new_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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