1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Revise handling of oldstyle/newstyle functions per recent discussions

in pghackers list.  Support for oldstyle internal functions is gone
(no longer needed, since conversion is complete) and pg_language entry
'internal' now implies newstyle call convention.  pg_language entry
'newC' is gone; both old and newstyle dynamically loaded C functions
are now called language 'C'.  A newstyle function must be identified
by an associated info routine.  See src/backend/utils/fmgr/README.
This commit is contained in:
Tom Lane
2000-11-20 20:36:57 +00:00
parent 99198ac6b8
commit 5bb2300b59
52 changed files with 571 additions and 328 deletions

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.19 2000/11/02 19:26:44 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_function.sgml,v 1.20 2000/11/20 20:36:46 tgl Exp $
Postgres documentation
-->
@ -119,8 +119,7 @@ CREATE FUNCTION <replaceable class="parameter">name</replaceable> ( [ <replaceab
<listitem>
<para>
May be '<literal>sql</literal>',
'<literal>C</literal>', '<literal>newC</literal>',
'<literal>internal</literal>', '<literal>newinternal</literal>',
'<literal>C</literal>', '<literal>internal</literal>',
or '<replaceable class="parameter">plname</replaceable>',
where '<replaceable class="parameter">plname</replaceable>'
is the name of a created procedural language. See
@ -258,7 +257,7 @@ CREATE
</para>
<para>
Two <literal>internal</literal> or <literal>newinternal</literal>
Two <literal>internal</literal>
functions cannot have the same C name without causing
errors at link time. To get around that, give them different C names
(for example, use the argument types as part of the C names), then

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.13 2000/11/04 21:04:54 momjian Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_language.sgml,v 1.14 2000/11/20 20:36:46 tgl Exp $
Postgres documentation
-->
@ -163,7 +163,8 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
<note>
<para>
In <productname>Postgres</productname> 7.1 and later, call handlers
must adhere to the "new style" function manager interface.
must adhere to the "version 1" function manager interface, not the
old-style interface.
</para>
</note>
@ -180,7 +181,7 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
</para>
<para>
The call handler is called in the same way as any other new-style
The call handler is called in the same way as any other
function: it receives a pointer to a FunctionCallInfoData struct
containing argument values and information about the called function,
and it is expected to return a Datum result (and possibly set the
@ -269,9 +270,7 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
lanname | lanispl | lanpltrusted | lanplcallfoid | lancompiler
-------------+---------+--------------+---------------+-------------
internal | f | f | 0 | n/a
newinternal | f | f | 0 | n/a
C | f | f | 0 | /bin/cc
newC | f | f | 0 | /bin/cc
sql | f | f | 0 | postgres
</computeroutput>
</programlisting>
@ -279,8 +278,9 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
<para>
The call handler for a procedural language must normally be written
in C and registered as 'newinternal' or 'newC' language, depending
in C and registered as 'internal' or 'C' language, depending
on whether it is linked into the backend or dynamically loaded.
The call handler cannot use the old-style 'C' function interface.
</para>
<para>
@ -306,6 +306,8 @@ ERROR: PL handler function <replaceable class="parameter">funcname</replaceable
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
PG_FUNCTION_INFO_V1(plsample_call_handler);
Datum
plsample_call_handler(PG_FUNCTION_ARGS)
{
@ -344,7 +346,7 @@ plsample_call_handler(PG_FUNCTION_ARGS)
<programlisting>
CREATE FUNCTION plsample_call_handler () RETURNS opaque
AS '/usr/local/pgsql/lib/plsample.so'
LANGUAGE 'newC';
LANGUAGE 'C';
CREATE PROCEDURAL LANGUAGE 'plsample'
HANDLER plsample_call_handler
LANCOMPILER 'PL/Sample';

View File

@ -22,7 +22,7 @@
<para>
The trigger function must be created before the trigger is created as a
function taking no arguments and returning opaque. If the function is
written in C, it must follow the "new style" function manager interface.
written in C, it must use the "version 1" function manager interface.
</para>
<para>
@ -447,6 +447,8 @@ execution of Q) or after Q is done.
extern Datum trigf(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(trigf);
Datum
trigf(PG_FUNCTION_ARGS)
{
@ -513,7 +515,7 @@ trigf(PG_FUNCTION_ARGS)
<programlisting>
create function trigf () returns opaque as
'...path_to_so' language 'newC';
'...path_to_so' language 'C';
create table ttest (x int4);
</programlisting>

View File

@ -1,5 +1,5 @@
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.22 2000/10/23 00:46:06 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.23 2000/11/20 20:36:47 tgl Exp $
-->
<chapter id="xfunc">
@ -339,9 +339,9 @@ SELECT clean_EMP();
</para>
<para>
There are two procedural languages available with the standard
<productname>Postgres</productname> distribution (PLTCL and PLSQL), and other
languages can be defined.
There are currently three procedural languages available in the standard
<productname>Postgres</productname> distribution (PLSQL, PLTCL and
PLPERL), and other languages can be defined.
Refer to <xref linkend="xplang-title" endterm="xplang-title"> for
more information.
</para>
@ -366,12 +366,7 @@ SELECT clean_EMP();
<para>
Internal functions are declared in <command>CREATE FUNCTION</command>
with language name <literal>internal</literal> or
<literal>newinternal</literal>, depending on whether they follow the
old (pre-7.1) or new (7.1 and later) function call conventions.
The details of the call conventions are the same as for
<literal>C</literal> and <literal>newC</literal> functions respectively;
see the next section for details.
with language name <literal>internal</literal>.
</para>
</sect1>
@ -404,9 +399,9 @@ SELECT clean_EMP();
<para>
The string which specifies the object file (the first string in the AS
clause) should be the <emphasis>full path</emphasis> of the object
code file for the function, bracketed by quotation marks. If a
code file for the function, bracketed by single quote marks. If a
link symbol is given in the AS clause, the link symbol should also be
bracketed by single quotation marks, and should be exactly the
bracketed by single quote marks, and should be exactly the
same as the name of the function in the C source code. On Unix systems
the command <command>nm</command> will print all of the link
symbols in a dynamically loadable object.
@ -422,11 +417,11 @@ SELECT clean_EMP();
<para>
Two different calling conventions are currently used for C functions.
The "old style" (pre-<productname>Postgres</productname>-7.1) method
is selected by writing language name '<literal>C</literal>' in the
<command>CREATE FUNCTION</command> command, while the "new style"
(7.1 and later) method is selecting by writing language name
'<literal>newC</literal>'. Old-style functions are now deprecated
The newer "version 1" calling convention is indicated by writing
a <literal>PG_FUNCTION_INFO_V1()</literal> macro call for the function,
as illustrated below. Lack of such a macro indicates an old-style
("version 0") function. The language name specified in CREATE FUNCTION
is 'C' in either case. Old-style functions are now deprecated
because of portability problems and lack of functionality, but they
are still supported for compatibility reasons.
</para>
@ -484,7 +479,7 @@ SELECT clean_EMP();
<entry>include/postgres.h</entry>
</row>
<row>
<entry>char</entry>
<entry>"char"</entry>
<entry>char</entry>
<entry>N/A</entry>
</row>
@ -583,16 +578,6 @@ SELECT clean_EMP();
<entry>TimeInterval</entry>
<entry>utils/nabstime.h</entry>
</row>
<row>
<entry>uint2</entry>
<entry>uint16</entry>
<entry>include/c.h</entry>
</row>
<row>
<entry>uint4</entry>
<entry>uint32</entry>
<entry>include/c.h</entry>
</row>
<row>
<entry>xid</entry>
<entry>(XID *)</entry>
@ -694,7 +679,7 @@ typedef struct {
</para>
<para>
Obviously, the data field is not long enough to hold
Obviously, the data field shown here is not long enough to hold
all possible strings; it's impossible to declare such
a structure in <acronym>C</acronym>. When manipulating
variable-length types, we must be careful to allocate
@ -721,12 +706,12 @@ memmove(destination-&gt;data, buffer, 40);
</sect2>
<sect2>
<title>Old-style Calling Conventions for C-Language Functions</title>
<title>Version-0 Calling Conventions for C-Language Functions</title>
<para>
We present the "old style" calling convention first --- although
this approach is now deprecated, it's easier to get a handle on
initially. In the "old style" method, the arguments and result
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.
@ -854,26 +839,39 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
</para>
<para>
Although this old-style calling convention is simple to use,
Although this calling convention is simple to use,
it is not very portable; on some architectures there are problems
with passing smaller-than-int data types this way. Also, there is
no simple way to return a NULL result, nor to cope with NULL arguments
in any way other than making the function strict. The new-style
in any way other than making the function strict. The version-1
convention, presented next, overcomes these objections.
</para>
</sect2>
<sect2>
<title>New-style Calling Conventions for C-Language Functions</title>
<title>Version-1 Calling Conventions for C-Language Functions</title>
<para>
The new-style calling convention relies on macros to suppress most
The version-1 calling convention relies on macros to suppress most
of the complexity of passing arguments and results. The C declaration
of a new-style function is always
of a version-1 function is always
<programlisting>
Datum funcname(PG_FUNCTION_ARGS)
</programlisting>
Each actual argument is fetched using a PG_GETARG_xxx() macro that
In addition, the macro call
<programlisting>
PG_FUNCTION_INFO_V1(funcname);
</programlisting>
must appear in the same source file (conventionally it's written
just before the function itself). This macro call is not needed
for "internal"-language functions, since Postgres currently assumes
all internal functions are version-1. However, it is
<emphasis>required</emphasis> for dynamically-loaded functions.
</para>
<para>
In a version-1 function,
each actual argument is fetched using a PG_GETARG_xxx() macro that
corresponds to the argument's datatype, and the result is returned
using a PG_RETURN_xxx() macro for the return type.
</para>
@ -887,6 +885,8 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
#include "fmgr.h"
/* By Value */
PG_FUNCTION_INFO_V1(add_one);
Datum
add_one(PG_FUNCTION_ARGS)
@ -898,6 +898,8 @@ add_one(PG_FUNCTION_ARGS)
/* By Reference, Fixed Length */
PG_FUNCTION_INFO_V1(add_one_float8);
Datum
add_one_float8(PG_FUNCTION_ARGS)
{
@ -907,6 +909,8 @@ add_one_float8(PG_FUNCTION_ARGS)
PG_RETURN_FLOAT8(arg + 1.0);
}
PG_FUNCTION_INFO_V1(makepoint);
Datum
makepoint(PG_FUNCTION_ARGS)
{
@ -922,6 +926,8 @@ makepoint(PG_FUNCTION_ARGS)
/* By Reference, Variable Length */
PG_FUNCTION_INFO_V1(copytext);
Datum
copytext(PG_FUNCTION_ARGS)
{
@ -940,6 +946,8 @@ copytext(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(new_t);
}
PG_FUNCTION_INFO_V1(concat_text);
Datum
concat_text(PG_FUNCTION_ARGS)
{
@ -959,12 +967,11 @@ concat_text(PG_FUNCTION_ARGS)
<para>
The <command>CREATE FUNCTION</command> commands are the same as
for the old-style equivalents, except that the language is specified
as '<literal>newC</literal>' not '<literal>C</literal>'.
for the old-style equivalents.
</para>
<para>
At first glance, the new-style coding conventions may appear to be
At first glance, the version-1 coding conventions may appear to be
just pointless obscurantism. However, they do offer a number of
improvements, because the macros can hide unnecessary detail.
An example is that in coding add_one_float8, we no longer need to
@ -973,11 +980,14 @@ concat_text(PG_FUNCTION_ARGS)
to deal with fetching "toasted" (compressed or out-of-line) values.
The old-style copytext and concat_text functions shown above are
actually wrong in the presence of toasted values, because they don't
call pg_detoast_datum() on their inputs.
call pg_detoast_datum() on their inputs. (The handler for old-style
dynamically-loaded functions currently takes care of this detail,
but it does so less efficiently than is possible for a version-1
function.)
</para>
<para>
The new-style function call conventions also make it possible to
The version-1 function call conventions also make it possible to
test for NULL inputs to a non-strict function, return a NULL result
(from either strict or non-strict functions), return "set" results,
and implement trigger functions and procedural-language call handlers.
@ -1026,7 +1036,9 @@ c_overpaid(TupleTableSlot *t, /* the current instance of EMP */
return salary &gt; limit;
}
/* In new-style coding, the above would look like this: */
/* In version-1 coding, the above would look like this: */
PG_FUNCTION_INFO_V1(c_overpaid);
Datum
c_overpaid(PG_FUNCTION_ARGS)