Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
a32542a1
Commit
a32542a1
authored
Jan 12, 2001
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update information about compiling extension modules.
parent
6162432d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
354 additions
and
439 deletions
+354
-439
doc/src/sgml/dfunc.sgml
doc/src/sgml/dfunc.sgml
+245
-322
doc/src/sgml/programmer.sgml
doc/src/sgml/programmer.sgml
+1
-2
doc/src/sgml/xfunc.sgml
doc/src/sgml/xfunc.sgml
+108
-115
No files found.
doc/src/sgml/dfunc.sgml
View file @
a32542a1
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.1
1 2000/09/29 20:21:33
petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/dfunc.sgml,v 1.1
2 2001/01/12 22:15:32
petere Exp $
-->
-->
<chapter id="dfunc">
<sect2 id="dfunc">
<title id="dfunc-title">Linking Dynamically-Loaded Functions</title>
<title id="dfunc-title">Compiling and Linking Dynamically-Loaded Functions</title>
<para>
<para>
Before you are able to use your
After you have created and registered a user-defined
<productname>PostgreSQL</productname> extension function written in
function, your work is essentially done.
C they need to be compiled and linked in a special way in order to
<productname>Postgres</productname>,
allow it to be dynamically loaded as needed by the server. To be
however, must load the object code
precise, a <firstterm>shared library</firstterm> needs to be created.
(e.g., a <literal>.o</literal> file, or
</para>
a shared library) that implements your function. As
previously mentioned, <productname>Postgres</productname>
<para>
loads your code at
For more information you should read the documentation of your
runtime, as required. In order to allow your code to be
operating system, in particular the manual pages for the C compiler,
dynamically loaded, you may have to compile and
<command>cc</command>, and the link editor, <command>ld</command>.
link-edit it in a special way. This section briefly
In addition, the <productname>PostgreSQL</productname> source code
describes how to perform the compilation and
contains several working examples in the
link-editing required before you can load your user-defined
<filename>contrib</filename> directory. If you rely on these
functions into a running <productname>Postgres</productname> server.
examples you will make your modules dependent on the documentation
</para>
of the <productname>PostgreSQL</productname> source code, however.
</para>
<para>
Creating shared libraries is generally analoguous to linking
executables: first the source files are compiled into object files,
then the object files are linked together. The object files need to
be created as <firstterm>position-independent code</firstterm>
(<acronym>PIC</acronym>), which conceptually means that it can be
placed at an arbitrary location in memory when it is loaded by the
executable. (Object files intended for executables are not compiled
that way.) The command to link a shared library contains special
flags to distinguish it from linking an executable. --- At least
this is the theory. On some systems the practice is much uglier.
</para>
<para>
In the following examples we assume that your source code is in a
file <filename>foo.c</filename> and we will create an shared library
<filename>foo.so</filename>. The intermediate object file will be
called <filename>foo.o</filename> unless otherwise noted. A shared
library can contain more than one object file, but we only use one
here.
</para>
<para>
<!--
<!--
<tip>
Note: Reading GNU Libtool sources is generally a good way of figuring out
<para>
this information. The methods used within PostgreSQL source code are not
The old <productname>Postgres</productname> dynamic
necessarily ideal.
loading mechanism required
in-depth knowledge in terms of executable format, placement
and alignment of executable instructions within memory, etc.
on the part of the person writing the dynamic loader. Such
loaders tended to be slow and buggy. As of Version 4.2, the
<productname>Postgres</productname> dynamic loading mechanism
has been rewritten to use
the dynamic loading mechanism provided by the operating
system. This approach is generally faster, more reliable and
more portable than our previous dynamic loading mechanism.
The reason for this is that nearly all modern versions of
Unix use a dynamic loading mechanism to implement shared
libraries and must therefore provide a fast and reliable
mechanism. On the other hand, the object file must be
postprocessed a bit before it can be loaded into
<productname>Postgres</productname>. We
hope that the large increase in speed and reliability will
make up for the slight decrease in convenience.
</para>
</tip>
</para>
-->
-->
<para>
<variablelist>
You should expect to read (and reread, and re-reread) the
<varlistentry>
manual pages for the C compiler, cc(1), and the link
<term><productname>BSD/OS</productname></term>
editor, ld(1), if you have specific questions. In
addition, the contrib area (<filename>PGROOT/contrib</filename>)
and the regression test suites in the directory
<filename>PGROOT/src/test/regress</filename> contain several
working examples of this process. If you copy an example then
you should not have any problems.
</para>
<para>
The following terminology will be used below:
<itemizedlist>
<listitem>
<listitem>
<para>
<para>
<firstterm>Dynamic loading</firstterm>
The compiler flag to create <acronym>PIC</acronym> is
is what <productname>Postgres</productname> does to an object file. The
<option>-fpic</option>. The linker flag to create shared
object file is copied into the running <productname>Postgres</productname>
libraries is <option>-shared</option>.
server and the functions and variables within the
<programlisting>
file are made available to the functions within
gcc -fpic -c foo.c
the <productname>Postgres</productname> process.
ld -shared -o foo.so foo.o
<productname>Postgres</productname> does this using
</programlisting>
the dynamic loading mechanism provided by the
This is applicable as of version 4.0 of
operating system
.
<productname>BSD/OS</productname>
.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
<varlistentry>
<term><productname>FreeBSD</productname></term>
<listitem>
<listitem>
<para>
<para>
<firstterm>Loading and link editing</firstterm>
The compiler flag to create <acronym>PIC</acronym> is
is what you do to an object file in order to produce
<option>-fpic</option>. To create shared libraries the compiler
another kind of object file (e.g., an executable
flag is <option>-shared</option>.
program or a shared library). You perform
<programlisting>
this using the link editing program, ld(1).
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
This is applicable as of version 3.0 of
<productname>FreeBSD</productname>.
</para>
</para>
</listitem>
</listitem>
</itemizedlist>
</varlistentry>
</para>
<para>
<varlistentry>
The following general restrictions and notes also apply
<term><productname>HP-UX</productname></term>
to the discussion below:
<itemizedlist>
<listitem>
<listitem>
<para>
<para>
Paths given to the create function command must be
The compiler flag of the system compiler to create
absolute paths (i.e., start with "/") that refer to
<acronym>PIC</acronym> is <option>+z</option>. When using
directories visible on the machine on which the
<productname>GCC</productname> it's <option>-fpic</option>. The
<productname>Postgres</productname> server is running.
linker flag for shared libraries is <option>-b</option>. So
<programlisting>
<tip>
cc +z -c foo.c
<para>
</programlisting>
Relative paths do in fact work,
or
but are relative to
<programlisting>
the directory where the database resides (which is generally
gcc -fpic -c foo.c
invisible to the frontend application). Obviously, it makes
</programlisting>
no sense to make the path relative to the directory in which
and then
the user started the frontend application, since the server
<programlisting>
could be running on a completely different machine!
ld -b -o foo.sl foo.o
</para>
</programlisting>
</tip>
<productname>HP-UX</productname> uses the extension
<filename>.sl</filename> for shared libraries, unlike most other
systems.
</para>
</para>
</listitem>
</listitem>
</varlistentry>
<varlistentry>
<term><productname>Irix</productname></term>
<listitem>
<listitem>
<para>
<para>
The <productname>Postgres</productname> user must be able to traverse the path
<acronym>PIC</acronym> is the default, no special compiler
given to the create function command and be able to
options are necessary. The linker option to produce shared
read the object file. This is because the <productname>Postgres</productname>
libraries is <option>-shared</option>.
server runs as the <productname>Postgres</productname> user, not as the user
<programlisting>
who starts up the frontend process. (Making the
cc -c foo.c
file or a higher-level directory unreadable and/or
ld -shared -o foo.so foo.o
unexecutable by the "postgres" user is an extremely
</programlisting>
common mistake.)
</para>
</para>
</listitem>
</listitem>
</varlistentry>
<varlistentry>
<term><productname>Linux</productname></term>
<listitem>
<listitem>
<para>
<para>
Symbol names defined within object files must not
The compiler flag to create <acronym>PIC</acronym> is
conflict with each other or with symbols defined in
<option>-fpic</option>. On some platforms in some situations
<productname>Postgres</productname>.
<option>-fPIC</option> must be used if <option>-fpic</option>
does not work. Refer to the GCC manual for more information.
The compiler flag to create a shared library is
<option>-shared</option>. A complete example looks like this:
<programlisting>
cc -fpic -c foo.c
cc -shared -o foo.so foo.o
</programlisting>
</para>
</para>
</listitem>
</listitem>
</varlistentry>
<varlistentry>
<term><productname>NetBSD</productname></term>
<listitem>
<listitem>
<para>
<para>
The GNU C compiler usually does not provide the special
The compiler flag to create <acronym>PIC</acronym> is
options that are required to use the operating
<option>-fpic</option>. For <acronym>ELF</acronym> systems, the
system's dynamic loader interface. In such cases,
compiler with the flag <option>-shared</option> is used to link
the C compiler that comes with the operating system
shared libraries. On the older non-ELF systems, <literal>ld
must be used.
-Bshareable</literal> is used.
<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
</para>
</para>
</listitem>
</listitem>
</itemizedlist>
</varlistentry>
</para>
<sect1 id="dload-linux">
<varlistentry>
<title>Linux</title>
<term><productname>OpenBSD</productname></term>
<listitem>
<para>
<para>
Under Linux ELF, object files can be generated by specifying the compiler
The compiler flag to create <acronym>PIC</acronym> is
flag -fpic.
<option>-fpic</option>. <literal>ld -Bshareable</literal> is
</para>
used to link shared libraries.
<programlisting>
<para>
gcc -fpic -c foo.c
For example,
ld -Bshareable -o foo.so foo.o
<programlisting>
</programlisting>
# simple Linux example
</para>
% cc -fpic -c <replaceable>foo.c</replaceable>
</listitem>
</programlisting>
</varlistentry>
produces an object file called <replaceable>foo.o</replaceable>
that can then be
dynamically loaded into <productname>Postgres</productname>.
No additional loading or link-editing must be performed.
</para>
</sect1>
<!--
<sect1 id="dload-ultrix">
<title><acronym>ULTRIX</acronym></title>
<para>
It is very easy to build dynamically-loaded object
files under ULTRIX. ULTRIX does not have any shared library
mechanism and hence does not place any restrictions on
the dynamic loader interface. On the other
hand, we had to (re)write a non-portable dynamic loader
ourselves and could not use true shared libraries.
Under ULTRIX, the only restriction is that you must
produce each object file with the option -G 0. (Notice
that that's the numeral ``0'' and not the letter
``O''). For example,
<programlisting>
# simple ULTRIX example
% cc -G 0 -c foo.c
</programlisting>
produces an object file called foo.o that can then be
dynamically loaded into <productname>Postgres</productname>.
No additional loading or link-editing must be performed.
</para>
</sect1>
-->
<sect1 id="dload-osf">
<title><acronym>DEC OSF/1</acronym></title>
<para>
Under DEC OSF/1, you can take any simple object file
and produce a shared object file by running the ld command
over it with the correct options. The commands to
do this look like:
<programlisting>
# simple DEC OSF/1 example
% cc -c foo.c
% ld -shared -expect_unresolved '*' -o foo.so foo.o
</programlisting>
The resulting shared object file can then be loaded
<varlistentry>
into <productname>Postgres</productname>. When specifying the object file name to
<term>Digital Unix/Tru64 UNIX</term>
the create function command, one must give it the name
of the shared object file (ending in .so) rather than
the simple object file.
<
tip
>
<
listitem
>
<para>
<para>
Actually, <productname>Postgres</productname> does not care
<acronym>PIC</acronym> is the default, so the compilation command
what you name the
is the usual one. <command>ld</command> with special options is
file as long as it is a shared object file. If you prefer
used to do the linking:
to name your shared object files with the extension .o, this
<programlisting>
is fine with <productname>Postgres</productname>
cc -c foo.c
so long as you make sure that the correct
ld -shared -expect_unresolved '*' -o foo.so foo.o
file name is given to the create function command. In
</programlisting>
other words, you must simply be consistent. However, from a
The same procedure is used with GCC instead of the system
pragmatic point of view, we discourage this practice because
compiler; no special options are required.
you will undoubtedly confuse yourself with regards to which
files have been made into shared object files and which have
not. For example, it's very hard to write Makefiles to do
the link-editing automatically if both the object file and
the shared object file end in .o!
</para>
</para>
</tip>
</listitem>
</varlistentry>
If the file you specify is
not a shared object, the backend will hang!
</para>
</sect1>
<sect1 id="dload-other">
<varlistentry>
<title>
<term><productname>Solaris</productname></term>
<acronym>SunOS 4.x</acronym>, <acronym>Solaris 2.x</acronym> and
<listitem>
<acronym>HP-UX</acronym></title>
<para>
The compiler flag to create <acronym>PIC</acronym> is
<option>-KPIC</option> with the Sun compiler and
<option>-fpic</option> with <productname>GCC</productname>. To
link shared libraries, the compiler option is
<option>-G</option> with either compiler or alternatively
<option>-shared</option> with <productname>GCC</productname>.
<programlisting>
cc -KPIC -c foo.c
cc -G -o foo.so foo.o
</programlisting>
or
<programlisting>
gcc -fpic -c foo.c
gcc -G -o foo.so foo.o
</programlisting>
</para>
</listitem>
</varlistentry>
<para>
<varlistentry>
Under SunOS 4.x, Solaris 2.x and HP-UX, the simple
<term><productname>Unixware</productname></term>
object file must be created by compiling the source
<listitem>
file with special compiler flags and a shared library
<para>
must be produced.
The compiler flag to create <acronym>PIC</acronym> is <option>-K
The necessary steps with HP-UX are as follows. The +z
PIC</option> with the SCO compiler and <option>-fpic</option>
flag to the HP-UX C compiler produces
with <productname>GCC</productname>. To link shared libraries,
<firstterm>Position Independent Code</firstterm> (PIC)
the compiler option is <option>-G</option> with the SCO compiler
and the +u flag removes
and <option>-shared</option> with
some alignment restrictions that the PA-RISC architecture
<productname>GCC</productname>.
normally enforces. The object file must be turned
<programlisting>
into a shared library using the HP-UX link editor with
cc -K PIC -c foo.c
the -b option. This sounds complicated but is actually
cc -G -o foo.so foo.o
very simple, since the commands to do it are just:
</programlisting>
or
<programlisting>
gcc -fpic -c foo.c
gcc -shared -o foo.so foo.o
</programlisting>
</para>
</listitem>
</varlistentry>
<programlisting>
</variablelist>
# simple HP-UX example
</para>
% cc +z +u -c foo.c
% ld -b -o foo.sl foo.o
</programlisting>
</para>
<para
>
<tip
>
As with the .so files mentioned in the last subsection,
<para>
the create function command must be told which file is
If you want to package your extension modules for wide distribution
the correct file to load (i.e., you must give it the
you should consider using <ulink
location of the shared library, or .sl file).
url="http://www.gnu.org/software/libtool/"><productname>GNU
Under SunOS 4.x, the commands look like:
Libtool</productname></ulink> for building shared libraries. It
<programlisting>
encapsulates the platform differences into a general and powerful
# simple SunOS 4.x example
interface. Serious packaging also requires considerations about
% cc -PIC -c foo.c
library versioning, symbol resolution methods, and other issues.
% ld -dc -dp -Bdynamic -o foo.so foo.o
</para>
</programlisting
>
</tip
>
and the equivalent lines under Solaris 2.x are:
<para>
<programlisting>
The resulting shared library file can then be loaded into
# simple Solaris 2.x example
<productname>Postgres</productname>. When specifying the file name
% cc -K PIC -c foo.c
to the <command>CREATE FUNCTION</command> command, one must give it
% ld -G -Bdynamic -o foo.so foo.o
the name of the shared library file (ending in
</programlisting>
<filename>.so</filename>) rather than the simple object file.
or
<programlisting>
# simple Solaris 2.x example
% gcc -fPIC -c foo.c
% ld -G -Bdynamic -o foo.so foo.o
</programlisting>
</para>
<note>
<para>
<para>
When linking shared libraries, you may have to specify
Actually, <productname>Postgres</productname> does not care what
some additional shared libraries (typically system
you name the file as long as it is a shared library file.
libraries, such as the C and math libraries) on your ld
command line.
</para>
</para>
</sect1>
</note>
<!--
Paths given to the <command>CREATE FUNCTION</command> command must
Future integration: Create separate sections for these operating
be absolute paths (i.e., start with <literal>/</literal>) that refer
systems and integrate the info from this old man page.
to directories visible on the machine on which the
- thomas 2000-04-21
<productname>Postgres</productname> server is running. Relative
paths do in fact work, but are relative to the directory where the
database resides (which is generally invisible to the frontend
application). Obviously, it makes no sense to make the path
relative to the directory in which the user started the frontend
application, since the server could be running on a completely
different machine! The user id the
<productname>Postgres</productname> server runs as must be able to
traverse the path given to the <command>CREATE FUNCTION</command>
command and be able to read the shared library file. (Making the
file or a higher-level directory not readable and/or not executable
by the <quote>postgres</quote> user is a common mistake.)
</para>
Under HP-UX, DEC OSF/1, AIX and SunOS 4, all object files must be
<!--
turned into
.IR "shared libraries"
using the operating system's native object file loader,
.IR ld(1).
.PP
Under HP-UX, an object file must be compiled using the native HP-UX C
compiler,
.IR /bin/cc ,
with both the \*(lq+z\*(rq and \*(lq+u\*(rq flags turned on. The
first flag turns the object file into \*(lqposition-independent
code\*(rq (PIC); the second flag removes some alignment restrictions
that the PA-RISC architecture normally enforces. The object file must
then be turned into a shared library using the HP-UX loader,
.IR /bin/ld .
The command lines to compile a C source file, \*(lqfoo.c\*(rq, look
like:
.nf
cc <other flags> +z +u -c foo.c
ld <other flags> -b -o foo.sl foo.o
.fi
The object file name in the
.BR as
clause should end in \*(lq.sl\*(rq.
.PP
An extra step is required under versions of HP-UX prior to 9.00. If
the Postgres header file
.nf
include/c.h
.fi
is not included in the source file, then the following line must also
be added at the top of every source file:
.nf
#pragma HP_ALIGN HPUX_NATURAL_S500
.fi
However, this line must not appear in programs compiled under HP-UX
9.00 or later.
.PP
Under DEC OSF/1, an object file must be compiled and then turned
into a shared library using the OSF/1 loader,
.IR /bin/ld .
In this case, the command lines look like:
.nf
cc <other flags> -c foo.c
ld <other flags> -shared -expect_unresolved '*' -o foo.so foo.o
.fi
The object file name in the
.BR as
clause should end in \*(lq.so\*(rq.
.PP
Under SunOS 4, an object file must be compiled and then turned into a
shared library using the SunOS 4 loader,
.IR /bin/ld .
The command lines look like:
.nf
cc <other flags> -PIC -c foo.c
ld <other flags> -dc -dp -Bdynamic -o foo.so foo.o
.fi
The object file name in the
.BR as
clause should end in \*(lq.so\*(rq.
.PP
Under AIX, object files are compiled normally but building the shared
Under AIX, object files are compiled normally but building the shared
library requires a couple of steps. First, create the object file:
library requires a couple of steps. First, create the object file:
.nf
.nf
...
@@ -389,7 +312,7 @@ procedure.
...
@@ -389,7 +312,7 @@ procedure.
-->
-->
</chapter
>
</sect2
>
<!-- Keep this comment at the end of the file
<!-- Keep this comment at the end of the file
Local variables:
Local variables:
...
...
doc/src/sgml/programmer.sgml
View file @
a32542a1
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.
29 2000/11/24 17:44:21
petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/programmer.sgml,v 1.
30 2001/01/12 22:15:32
petere Exp $
PostgreSQL Programmer's Guide.
PostgreSQL Programmer's Guide.
-->
-->
...
@@ -72,7 +72,6 @@ PostgreSQL Programmer's Guide.
...
@@ -72,7 +72,6 @@ PostgreSQL Programmer's Guide.
&indexcost;
&indexcost;
&gist;
&gist;
&xplang;
&xplang;
&dfunc;
<!-- reference -->
<!-- reference -->
...
...
doc/src/sgml/xfunc.sgml
View file @
a32542a1
<!--
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.2
6 2000/12/26 00:10:37
petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.2
7 2001/01/12 22:15:32
petere Exp $
-->
-->
<chapter id="xfunc">
<chapter id="xfunc">
...
@@ -632,10 +632,10 @@ SELECT clean_EMP();
...
@@ -632,10 +632,10 @@ SELECT clean_EMP();
the <literal>int4</literal> type on Unix
the <literal>int4</literal> type on Unix
machines might be:
machines might be:
<programlisting>
<programlisting>
/* 4-byte integer, passed by value */
/* 4-byte integer, passed by value */
typedef int int4;
typedef int int4;
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -643,13 +643,13 @@ typedef int int4;
...
@@ -643,13 +643,13 @@ typedef int int4;
be passed by-reference. For example, here is a sample
be passed by-reference. For example, here is a sample
implementation of a <productname>Postgres</productname> type:
implementation of a <productname>Postgres</productname> type:
<programlisting>
<programlisting>
/* 16-byte structure, passed by reference */
/* 16-byte structure, passed by reference */
typedef struct
typedef struct
{
{
double x, y;
double x, y;
} Point;
} Point;
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -670,12 +670,12 @@ typedef struct
...
@@ -670,12 +670,12 @@ typedef struct
(i.e., it includes the size of the length field
(i.e., it includes the size of the length field
itself). We can define the text type as follows:
itself). We can define the text type as follows:
<programlisting>
<programlisting>
typedef struct {
typedef struct {
int4 length;
int4 length;
char data[1];
char data[1];
} text;
} text;
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -687,7 +687,7 @@ typedef struct {
...
@@ -687,7 +687,7 @@ typedef struct {
For example, if we wanted to store 40 bytes in a text
For example, if we wanted to store 40 bytes in a text
structure, we might use a code fragment like this:
structure, we might use a code fragment like this:
<programlisting>
<programlisting>
#include "postgres.h"
#include "postgres.h"
...
...
char buffer[40]; /* our source data */
char buffer[40]; /* our source data */
...
@@ -696,7 +696,7 @@ text *destination = (text *) palloc(VARHDRSZ + 40);
...
@@ -696,7 +696,7 @@ text *destination = (text *) palloc(VARHDRSZ + 40);
destination->length = VARHDRSZ + 40;
destination->length = VARHDRSZ + 40;
memmove(destination->data, buffer, 40);
memmove(destination->data, buffer, 40);
...
...
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -709,7 +709,7 @@ memmove(destination->data, buffer, 40);
...
@@ -709,7 +709,7 @@ memmove(destination->data, buffer, 40);
<title>Version-0 Calling Conventions for C-Language Functions</title>
<title>Version-0 Calling Conventions for C-Language Functions</title>
<para>
<para>
We present the
"old style"
calling convention first --- although
We present the
<quote>old style</quote>
calling convention first --- although
this approach is now deprecated, it's easier to get a handle on
this approach is now deprecated, it's easier to get a handle on
initially. In the version-0 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
of the C function are just declared in normal C style, but being
...
@@ -720,7 +720,7 @@ memmove(destination->data, buffer, 40);
...
@@ -720,7 +720,7 @@ memmove(destination->data, buffer, 40);
<para>
<para>
Here are some examples:
Here are some examples:
<programlisting>
<programlisting>
#include <string.h>
#include <string.h>
#include "postgres.h"
#include "postgres.h"
...
@@ -786,7 +786,7 @@ concat_text(text *arg1, text *arg2)
...
@@ -786,7 +786,7 @@ concat_text(text *arg1, text *arg2)
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
return new_text;
return new_text;
}
}
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -795,7 +795,7 @@ concat_text(text *arg1, text *arg2)
...
@@ -795,7 +795,7 @@ concat_text(text *arg1, text *arg2)
we could define the functions to <productname>Postgres</productname>
we could define the functions to <productname>Postgres</productname>
with commands like this:
with commands like this:
<programlisting>
<programlisting>
CREATE FUNCTION add_one(int4) RETURNS int4
CREATE FUNCTION add_one(int4) RETURNS int4
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
WITH (isStrict);
WITH (isStrict);
...
@@ -817,7 +817,7 @@ CREATE FUNCTION copytext(text) RETURNS text
...
@@ -817,7 +817,7 @@ CREATE FUNCTION copytext(text) RETURNS text
CREATE FUNCTION concat_text(text, text) RETURNS text
CREATE FUNCTION concat_text(text, text) RETURNS text
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
AS '<replaceable>PGROOT</replaceable>/tutorial/funcs.so' LANGUAGE 'c'
WITH (isStrict);
WITH (isStrict);
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -855,13 +855,13 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
...
@@ -855,13 +855,13 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
The version-1 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 the complexity of passing arguments and results. The C declaration
of a version-1 function is always
of a version-1 function is always
<programlisting>
<programlisting>
Datum funcname(PG_FUNCTION_ARGS)
Datum funcname(PG_FUNCTION_ARGS)
</programlisting>
</programlisting>
In addition, the macro call
In addition, the macro call
<programlisting>
<programlisting>
PG_FUNCTION_INFO_V1(funcname);
PG_FUNCTION_INFO_V1(funcname);
</programlisting>
</programlisting>
must appear in the same source file (conventionally it's written
must appear in the same source file (conventionally it's written
just before the function itself). This macro call is not needed
just before the function itself). This macro call is not needed
for "internal"-language functions, since Postgres currently assumes
for "internal"-language functions, since Postgres currently assumes
...
@@ -870,16 +870,18 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
...
@@ -870,16 +870,18 @@ CREATE FUNCTION concat_text(text, text) RETURNS text
</para>
</para>
<para>
<para>
In a version-1 function,
In a version-1 function, each actual argument is fetched using a
each actual argument is fetched using a PG_GETARG_xxx() macro that
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
corresponds to the argument's datatype, and the result is returned
macro that corresponds to the argument's datatype, and the result
using a PG_RETURN_xxx() macro for the return type.
is returned using a
<function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
macro for the return type.
</para>
</para>
<para>
<para>
Here we show the same functions as above, coded in new style:
Here we show the same functions as above, coded in new style:
<programlisting>
<programlisting>
#include <string.h>
#include <string.h>
#include "postgres.h"
#include "postgres.h"
#include "fmgr.h"
#include "fmgr.h"
...
@@ -962,7 +964,7 @@ concat_text(PG_FUNCTION_ARGS)
...
@@ -962,7 +964,7 @@ concat_text(PG_FUNCTION_ARGS)
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
strncat(VARDATA(new_text), VARDATA(arg2), VARSIZE(arg2)-VARHDRSZ);
PG_RETURN_TEXT_P(new_text);
PG_RETURN_TEXT_P(new_text);
}
}
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -971,27 +973,30 @@ concat_text(PG_FUNCTION_ARGS)
...
@@ -971,27 +973,30 @@ concat_text(PG_FUNCTION_ARGS)
</para>
</para>
<para>
<para>
At first glance, the version-1 coding conventions may appear to
be
At first glance, the version-1 coding conventions may appear to
just pointless obscurantism. However, they do offer a number of
be just pointless obscurantism. However, they do offer a number
improvements, because the macros can hide unnecessary detail.
of
improvements, because the macros can hide unnecessary detail.
An example is that in coding add_one_float8, we no longer need to
An example is that in coding add_one_float8, we no longer need to
be aware that float8 is a pass-by-reference type. Another example
be aware that float8 is a pass-by-reference type. Another
is that the GETARG macros for variable-length types hide the need
example is that the GETARG macros for variable-length types hide
to deal with fetching "toasted" (compressed or out-of-line) values.
the need to deal with fetching "toasted" (compressed or
The old-style copytext and concat_text functions shown above are
out-of-line) values. The old-style <function>copytext</function>
actually wrong in the presence of toasted values, because they don't
and <function>concat_text</function> functions shown above are
call pg_detoast_datum() on their inputs. (The handler for old-style
actually wrong in the presence of toasted values, because they
dynamically-loaded functions currently takes care of this detail,
don't call <function>pg_detoast_datum()</function> on their
but it does so less efficiently than is possible for a version-1
inputs. (The handler for old-style dynamically-loaded functions
function.)
currently takes care of this detail, but it does so less
efficiently than is possible for a version-1 function.)
</para>
</para>
<para>
<para>
The version-1 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
test for NULL inputs to a non-strict function, return a NULL
(from either strict or non-strict functions), return "set" results,
result (from either strict or non-strict functions), return
and implement trigger functions and procedural-language call handlers.
<quote>set</quote> results, and implement trigger functions and
For more details see <filename>src/backend/utils/fmgr/README</filename>.
procedural-language call handlers. For more details see
<filename>src/backend/utils/fmgr/README</filename> in the source
distribution.
</para>
</para>
</sect2>
</sect2>
...
@@ -1011,15 +1016,15 @@ concat_text(PG_FUNCTION_ARGS)
...
@@ -1011,15 +1016,15 @@ concat_text(PG_FUNCTION_ARGS)
function as an opaque structure of type <literal>TUPLE</literal>.
function as an opaque structure of type <literal>TUPLE</literal>.
Suppose we want to write a function to answer the query
Suppose we want to write a function to answer the query
<programlisting>
<programlisting>
* SELECT name, c_overpaid(EMP
, 1500) AS overpaid
SELECT name, c_overpaid(emp
, 1500) AS overpaid
FROM EMP
FROM emp
WHERE name = 'Bill' or
name = 'Sam';
WHERE name = 'Bill' OR
name = 'Sam';
</programlisting>
</programlisting>
In the query above, we can define c_overpaid as:
In the query above, we can define c_overpaid as:
<programlisting>
<programlisting>
#include "postgres.h"
#include "postgres.h"
#include "executor/executor.h" /* for GetAttributeByName() */
#include "executor/executor.h" /* for GetAttributeByName() */
...
@@ -1055,31 +1060,31 @@ c_overpaid(PG_FUNCTION_ARGS)
...
@@ -1055,31 +1060,31 @@ c_overpaid(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(salary > limit);
PG_RETURN_BOOL(salary > limit);
}
}
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
<function>GetAttributeByName</function> is the
<function>GetAttributeByName</function> is the
<productname>Postgres</productname> system function that
<productname>Postgres</productname> system function that
returns attributes out of the current instance. It has
returns attributes out of the current instance. It has
three arguments: the argument of type
TupleTableSlot*
passed into
three arguments: the argument of type
<type>TupleTableSlot*</type>
passed into
the function, the name of the desired attribute, and a
the function, the name of the desired attribute, and a
return parameter that tells whether the attribute
return parameter that tells whether the attribute
is null. <function>GetAttributeByName</function> returns a Datum
is null. <function>GetAttributeByName</function> returns a Datum
value that you can convert to the proper datatype by using the
value that you can convert to the proper datatype by using the
appropriate
DatumGetXXX()
macro.
appropriate
<function>DatumGet<replaceable>XXX</replaceable>()</function>
macro.
</para>
</para>
<para>
<para>
The following query lets <productname>Postgres</productname>
The following query lets <productname>Postgres</productname>
know about the
c_overpaid
function:
know about the
<function>c_overpaid</function>
function:
<programlisting>
<programlisting>
CREATE FUNCTION c_overpaid(
EMP
, int4)
CREATE FUNCTION c_overpaid(
emp
, int4)
RETURNS bool
RETURNS bool
AS '<replaceable>PGROOT</replaceable>/tutorial/obj/funcs.so'
AS '<replaceable>PGROOT</replaceable>/tutorial/obj/funcs.so'
LANGUAGE 'c';
LANGUAGE 'c';
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -1096,7 +1101,7 @@ LANGUAGE 'c';
...
@@ -1096,7 +1101,7 @@ LANGUAGE 'c';
We now turn to the more difficult task of writing
We now turn to the more difficult task of writing
programming language functions. Be warned: this section
programming language functions. Be warned: this section
of the manual will not make you a programmer. You must
of the manual will not make you a programmer. You must
have a good understanding of <acronym>C</acronym>
have a good understanding of <acronym>C</acronym>
(including the use of pointers and the malloc memory manager)
(including the use of pointers and the malloc memory manager)
before trying to write <acronym>C</acronym> functions for
before trying to write <acronym>C</acronym> functions for
use with <productname>Postgres</productname>. While it may
use with <productname>Postgres</productname>. While it may
...
@@ -1113,20 +1118,6 @@ LANGUAGE 'c';
...
@@ -1113,20 +1118,6 @@ LANGUAGE 'c';
are written in <acronym>C</acronym>.
are written in <acronym>C</acronym>.
</para>
</para>
<para>
C functions with base type arguments can be written in a
straightforward fashion. The C equivalents of built-in Postgres types
are accessible in a C file if
<filename><replaceable>PGROOT</replaceable>/src/backend/utils/builtins.h</filename>
is included as a header file. This can be achieved by having
<programlisting>
#include <utils/builtins.h>
</programlisting>
at the top of the C source file.
</para>
<para>
<para>
The basic rules for building <acronym>C</acronym> functions
The basic rules for building <acronym>C</acronym> functions
are as follows:
are as follows:
...
@@ -1134,66 +1125,65 @@ LANGUAGE 'c';
...
@@ -1134,66 +1125,65 @@ LANGUAGE 'c';
<itemizedlist>
<itemizedlist>
<listitem>
<listitem>
<para>
<para>
Most of the header (include) files for
The relevant header (include) files are installed under
<productname>Postgres</productname>
<filename>/usr/local/pgsql/include</filename> or equivalent.
should already be installed in
You can use <literal>pg_config --includedir</literal> to find
<filename><replaceable>PGROOT</replaceable>/include</filename> (see Figure 2).
out where it is on your system (or the system that your
You should always include
users will be running on). For very low-level work you might
need to have a complete <productname>PostgreSQL</productname>
<programlisting>
source tree available.
-I$PGROOT/include
</para>
</programlisting>
</listitem>
on your cc command lines. Sometimes, you may
find that you require header files that are in
the server source itself (i.e., you need a file
we neglected to install in include). In those
cases you may need to add one or more of
<programlisting>
-I$PGROOT/src/backend
-I$PGROOT/src/backend/include
-I$PGROOT/src/backend/port/<PORTNAME>
-I$PGROOT/src/backend/obj
</programlisting>
(where <PORTNAME> is the name of the port, e.g.,
<listitem>
alpha or sparc).
<para>
When allocating memory, use the
<productname>Postgres</productname> routines
<function>palloc</function> and <function>pfree</function>
instead of the corresponding <acronym>C</acronym> library
routines <function>malloc</function> and
<function>free</function>. The memory allocated by
<function>palloc</function> will be freed automatically at the
end of each transaction, preventing memory leaks.
</para>
</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
When allocating memory, use the
Always zero the bytes of your structures using
<
productname>Postgres</productname>
<
function>memset</function> or <function>bzero</function>.
routines palloc and pfree instead of the
Several routines (such as the hash access method, hash join
corresponding <acronym>C</acronym> library routines
and the sort algorithm) compute functions of the raw bits
malloc and free.
contained in your structure. Even if you initialize all
The memory allocated by palloc will be freed
fields of your structure, there may be several bytes of
a
utomatically at the end of each transaction,
a
lignment padding (holes in the structure) that may contain
preventing memory leak
s.
garbage value
s.
</para>
</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
Always zero the bytes of your structures using
Most of the internal <productname>Postgres</productname> types
memset or bzero. Several routines (such as the
are declared in <filename>postgres.h</filename>, the function
hash access method, hash join and the sort algorithm)
manager interfaces (<symbol>PG_FUNCTION_ARGS</symbol>, etc.)
compute functions of the raw bits contained in
are in <filename>fmgr.h</filename>, so you will need to
your structure. Even if you initialize all fields
include at least these two files. Including
of your structure, there may b
e
<filename>postgres.h</filename> will also includ
e
several bytes of alignment padding (holes in the
<filename>elog.h</filename> and <filename>palloc.h</filename>
structure) that may contain garbage values
.
for you
.
</para>
</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
Most of the internal <productname>Postgres</productname>
Symbol names defined within object files must not conflict
types are declared in <filename>postgres.h</filename>,
with each other or with symbols defined in the
so it's a good
<productname>PostgreSQL</productname> server executable. You
idea to always include that file as well. Including
will have to rename your functions or variables if you get
postgres.h will also include elog.h and palloc.h for you
.
error messages to this effect
.
</para>
</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
Compiling and loading your object code so that
Compiling and loading your object code so that
...
@@ -1208,6 +1198,9 @@ LANGUAGE 'c';
...
@@ -1208,6 +1198,9 @@ LANGUAGE 'c';
</itemizedlist>
</itemizedlist>
</para>
</para>
</sect2>
</sect2>
&dfunc;
</sect1>
</sect1>
<sect1 id="xfunc-overload">
<sect1 id="xfunc-overload">
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment