aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/dfunc.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/dfunc.sgml')
-rw-r--r--doc/src/sgml/dfunc.sgml242
1 files changed, 242 insertions, 0 deletions
diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml
new file mode 100644
index 00000000000..7a719b7ed3e
--- /dev/null
+++ b/doc/src/sgml/dfunc.sgml
@@ -0,0 +1,242 @@
+<Chapter>
+<Title>Linking Dynamically-Loaded Functions</Title>
+
+<Para>
+ After you have created and registered a user-defined
+ function, your work is essentially done. <ProductName>Postgres</ProductName>,
+ however, must load the object code (e.g., a <FileName>.o</FileName> file, or
+ a shared library) that implements your function. As
+ previously mentioned, <ProductName>Postgres</ProductName> loads your code at
+ runtime, as required. In order to allow your code to be
+ dynamically loaded, you may have to compile and
+ linkedit it in a special way. This section briefly
+ describes how to perform the compilation and
+ linkediting required before you can load your user-defined
+ functions into a running <ProductName>Postgres</ProductName> server. Note that
+ this process has changed as of Version 4.2.
+<Tip>
+<Para>
+The old <ProductName>Postgres</ProductName> dynamic
+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>
+ You should expect to read (and reread, and re-reread) the
+ manual pages for the C compiler, cc(1), and the link
+ editor, ld(1), if you have specific questions. In
+ addition, the regression test suites in the directory
+ <FileName>PGROOT/src/regress</FileName> contain several
+ working examples of this process. If you copy what these
+ tests do, you should not have any problems.
+ The following terminology will be used below:
+<ItemizedList>
+<ListItem>
+<Para>
+ <FirstTerm>Dynamic loading</FirstTerm>
+ is what <ProductName>Postgres</ProductName> does to an object file. The
+ object file is copied into the running <ProductName>Postgres</ProductName>
+ server and the functions and variables within the
+ file are made available to the functions within
+ the <ProductName>Postgres</ProductName> process. <ProductName>Postgres</ProductName> does this using
+ the dynamic loading mechanism provided by the
+ operating system.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+ <FirstTerm>Loading and link editing</FirstTerm>
+ is what you do to an object file in order to produce
+ another kind of object file (e.g., an executable
+ program or a shared library). You perform
+ this using the link editing program, ld(1).
+</Para>
+</ListItem>
+</ItemizedList>
+</Para>
+
+<Para>
+ The following general restrictions and notes also apply
+ to the discussion below:
+<ItemizedList>
+<ListItem>
+<Para>
+Paths given to the create function command must be
+ absolute paths (i.e., start with "/") that refer to
+ directories visible on the machine on which the
+ <ProductName>Postgres</ProductName> server is running.
+<Tip>
+<Para>
+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!
+</Para>
+</Tip>
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+The <ProductName>Postgres</ProductName> user must be able to traverse the path
+ given to the create function command and be able to
+ read the object file. This is because the <ProductName>Postgres</ProductName>
+ server runs as the <ProductName>Postgres</ProductName> user, not as the user
+ who starts up the frontend process. (Making the
+ file or a higher-level directory unreadable and/or
+ unexecutable by the "postgres" user is an extremely
+ common mistake.)
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+Symbol names defined within object files must not
+ conflict with each other or with symbols defined in
+ <ProductName>Postgres</ProductName>.
+</Para>
+</ListItem>
+<ListItem>
+<Para>
+The GNU C compiler usually does not provide the special
+ options that are required to use the operating
+ system's dynamic loader interface. In such cases,
+ the C compiler that comes with the operating system
+ must be used.
+</Para>
+</ListItem>
+</ItemizedList>
+
+<Sect1>
+<Title><Acronym>ULTRIX</Acronym></Title>
+
+<Para>
+ It is very easy to build dynamically-loaded object
+ files under ULTRIX. ULTRIX does not have any sharedlibrary
+ 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>
+<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
+ into <ProductName>Postgres</ProductName>. When specifying the object file name to
+ 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>
+<Para>
+Actually, <ProductName>Postgres</ProductName> does not care
+what you name the
+file as long as it is a shared object file. If you prefer
+to name your shared object files with the extension .o, this
+is fine with <ProductName>Postgres</ProductName> so long as you make sure that the correct
+file name is given to the create function command. In
+other words, you must simply be consistent. However, from a
+pragmatic point of view, we discourage this practice because
+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>
+</Tip>
+
+If the file you specify is
+ not a shared object, the backend will hang!
+</Para>
+</Sect1>
+
+<Sect1>
+<Title>
+<Acronym>SunOS 4.x</Acronym>, <Acronym>Solaris 2.x</Acronym> and <Acronym>HP-UX</Acronym></Title>
+
+<Para>
+ Under SunOS 4.x, Solaris 2.x and HP-UX, the simple
+ object file must be created by compiling the source
+ file with special compiler flags and a shared library
+ must be produced.
+ The necessary steps with HP-UX are as follows. The +z
+ flag to the HP-UX C compiler produces so-called
+ "Position Independent Code" (PIC) and the +u flag
+ removes
+ some alignment restrictions that the PA-RISC architecture
+ normally enforces. The object file must be turned
+ into a shared library using the HP-UX link editor with
+ the -b option. This sounds complicated but is actually
+ very simple, since the commands to do it are just:
+<ProgramListing>
+# simple HP-UX example
+ &percnt; cc +z +u -c foo.c
+ &percnt; ld -b -o foo.sl foo.o
+</ProgramListing>
+</Para>
+
+<Para>
+ As with the .so files mentioned in the last subsection,
+ the create function command must be told which file is
+ the correct file to load (i.e., you must give it the
+ location of the shared library, or .sl file).
+ Under SunOS 4.x, the commands look like:
+<ProgramListing>
+# simple SunOS 4.x example
+ &percnt; cc -PIC -c foo.c
+ &percnt; ld -dc -dp -Bdynamic -o foo.so foo.o
+</ProgramListing>
+
+ and the equivalent lines under Solaris 2.x are:
+<ProgramListing>
+# simple Solaris 2.x example
+ &percnt; cc -K PIC -c foo.c
+ or
+ &percnt; gcc -fPIC -c foo.c
+ &percnt; ld -G -Bdynamic -o foo.so foo.o
+</ProgramListing>
+</Para>
+
+<Para>
+ When linking shared libraries, you may have to specify
+ some additional shared libraries (typically system
+ libraries, such as the C and math libraries) on your ld
+ command line.
+</Para>
+</Sect1>
+</Chapter>