mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Overhaul plperl documentation.
This commit is contained in:
parent
1b68bcfad3
commit
c4bab5f29b
@ -1,60 +1,75 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.14 2002/01/08 16:13:41 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.15 2002/01/25 19:13:15 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter id="plperl">
|
<chapter id="plperl">
|
||||||
<title>PL/Perl - Perl Procedural Language</title>
|
<title>PL/Perl - Perl Procedural Language</title>
|
||||||
|
|
||||||
<indexterm zone="plperl">
|
<indexterm zone="plperl">
|
||||||
<primary>PL/Perl</primary>
|
<primary>PL/Perl</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<indexterm zone="plperl">
|
<indexterm zone="plperl">
|
||||||
<primary>Perl</primary>
|
<primary>Perl</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
|
||||||
<sect1 id="intro">
|
<para>
|
||||||
<title>Introduction</title>
|
PL/Perl is a loadable procedural language
|
||||||
|
that enables the <ulink url="http://www.perl.com">Perl</ulink> programming
|
||||||
|
language to be used to write
|
||||||
|
<productname>PostgreSQL</productname> functions.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<!-- **** PL/Perl overview **** -->
|
||||||
PL/Perl allows you to write functions in the <ulink
|
|
||||||
url="http://www.perl.com">Perl</ulink> programming language that may
|
|
||||||
be used in SQL queries as if they were built into
|
|
||||||
<productname>PostgreSQL</productname>.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<sect1 id="plperl-overview">
|
||||||
The PL/Perl interpreter (when installed as trusted interpreter with
|
<title>Overview</title>
|
||||||
default name <literal>plperl</>) is a full Perl interpreter. However, certain
|
|
||||||
operations have been disabled in order to maintain the security of
|
|
||||||
the system. In general, the operations that are restricted are
|
|
||||||
those that interact with the environment. This includes file handle
|
|
||||||
operations, <literal>require</literal>, and <literal>use</literal>
|
|
||||||
(for external modules). It should be noted that this security is
|
|
||||||
not absolute. Indeed, several Denial-of-Service attacks are still
|
|
||||||
possible - memory exhaustion and endless loops are two examples.
|
|
||||||
|
|
||||||
</para>
|
<para>
|
||||||
<para>
|
Normally, PL/Perl is installed as a <quote>trusted</> programming
|
||||||
When PL/Perl is installed as <quote>untrusted</> interpreter (with name <literal>plperlu</literal>),
|
language named <literal>plperl</>. In this setup, certain Perl
|
||||||
everything is permitted, and any Perl code can be loaded (by a superuser only).
|
operations are disabled to preserve security. In general, the operations
|
||||||
</para>
|
that are restricted are those that interact with the environment. This
|
||||||
|
includes file handle operations, <literal>require</literal>, and
|
||||||
|
<literal>use</literal> (for external modules).
|
||||||
|
There is no way to access internals of the
|
||||||
|
database backend or to gain OS-level access under the permissions of the
|
||||||
|
<productname>PostgreSQL</productname> user ID, as a C function can do.
|
||||||
|
Thus, any unprivileged database user may be
|
||||||
|
permitted to use this language.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
Sometimes it is desirable to write Perl functions that are not restricted
|
||||||
|
--- for example, one might want a Perl function that sends
|
||||||
|
mail. To handle these cases, PL/Perl can also be installed as an
|
||||||
|
<quote>untrusted</> language (usually named <literal>plperlu</>).
|
||||||
|
In this case the full Perl language is available. The writer of a PL/PerlU
|
||||||
|
function must take care that the function cannot be used to do anything
|
||||||
|
unwanted, since it will be able to do anything that could be done by
|
||||||
|
a user logged in as the database administrator. Note that the database
|
||||||
|
system allows only database superusers to create functions in untrusted
|
||||||
|
languages.
|
||||||
|
</para>
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="plperl-install">
|
<sect1 id="plperl-install">
|
||||||
<title>Building and Installing</title>
|
<title>Building and Installing PL/Perl</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
In order to build and install PL/Perl if you are installing
|
If the <option>--with-perl</option> option was supplied to the
|
||||||
<productname>PostgreSQL</productname> from source then the
|
|
||||||
<option>--with-perl</option> must be supplied to the
|
|
||||||
<indexterm><primary><filename>configure</filename></primary></indexterm>
|
<indexterm><primary><filename>configure</filename></primary></indexterm>
|
||||||
<filename>configure</filename> script. PL/Perl requires that, when
|
<filename>configure</filename> script,
|
||||||
<productname>Perl</productname> was installed, the
|
the <productname>PostgreSQL</productname> build process will attempt to
|
||||||
|
build the PL/Perl shared library and install it in the
|
||||||
|
<productname>PostgreSQL</productname> library directory.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
On most platforms, since PL/Perl is a shared library, the
|
||||||
<indexterm><primary>libperl</primary></indexterm>
|
<indexterm><primary>libperl</primary></indexterm>
|
||||||
<filename>libperl</filename> library was build as a shared object.
|
<filename>libperl</filename> library must be a shared library also.
|
||||||
At the time of this writing, this is almost never the case in the
|
At the time of this writing, this is almost never the case in prebuilt
|
||||||
Perl packages that are distributed with the operating systems. A
|
Perl packages. If this difficulty arises in your situation, a
|
||||||
message like this will appear during the build to point out this
|
message like this will appear during the build to point out this
|
||||||
fact:
|
fact:
|
||||||
<screen>
|
<screen>
|
||||||
@ -64,14 +79,14 @@ $Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.14 2002/01/08 16:13:41 pete
|
|||||||
*** the documentation for details.
|
*** the documentation for details.
|
||||||
</computeroutput>
|
</computeroutput>
|
||||||
</screen>
|
</screen>
|
||||||
Therefore it is likely that you will have to re-build and install
|
If you see this, you will have to re-build and install
|
||||||
<productname>Perl</productname> manually to be able to build
|
<productname>Perl</productname> manually to be able to build
|
||||||
PL/Perl.
|
PL/Perl. During the configuration process for
|
||||||
|
<productname>Perl</productname>, request a shared library.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
When you want to retry to build PL/Perl after having reinstalled
|
After having reinstalled Perl, change to the directory
|
||||||
Perl, then change to the directory
|
|
||||||
<filename>src/pl/plperl</filename> in the
|
<filename>src/pl/plperl</filename> in the
|
||||||
<productname>PostgreSQL</productname> source tree and issue the commands
|
<productname>PostgreSQL</productname> source tree and issue the commands
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -79,88 +94,131 @@ gmake clean
|
|||||||
gmake all
|
gmake all
|
||||||
gmake install
|
gmake install
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
to complete the build and installation of the PL/Perl shared library.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <command>createlang</command> command is used to install the
|
To install
|
||||||
language into a database.
|
PL/Perl and/or PL/PerlU in a particular database, use the
|
||||||
<screen>
|
<filename>createlang</filename> script, for example
|
||||||
<prompt>$</prompt> <userinput>createlang plperl template1</userinput>
|
<literal>createlang plperl <replaceable>dbname</></literal> or
|
||||||
</screen>
|
<literal>createlang plperlu <replaceable>dbname</></literal>.
|
||||||
Alternatively, to create untrusted interpreter (where functions can only
|
</para>
|
||||||
be created by a superuser, but the functions are not restricted), use:
|
|
||||||
<screen>
|
|
||||||
<prompt>$</prompt> <userinput>createlang plperlu template1</userinput>
|
|
||||||
</screen>
|
|
||||||
If it is installed into template1, all future databases will have
|
|
||||||
the language installed automatically.
|
|
||||||
</para>
|
|
||||||
</sect1>
|
|
||||||
|
|
||||||
<sect1 id="plperl-use">
|
<tip>
|
||||||
<title>Using PL/Perl</title>
|
<para>
|
||||||
|
If a language is installed into <literal>template1</>, all subsequently
|
||||||
|
created databases will have the language installed automatically.
|
||||||
|
</para>
|
||||||
|
</tip>
|
||||||
|
</sect1>
|
||||||
|
|
||||||
<para>
|
<!-- **** PL/Perl description **** -->
|
||||||
Assume you have the following table:
|
|
||||||
<programlisting>
|
<sect1 id="plperl-description">
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>PL/Perl Functions and Arguments</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To create a function in the PL/Perl language, use the standard syntax
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS '
|
||||||
|
# PL/Perl function body
|
||||||
|
' LANGUAGE plperl;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
PL/PerlU is the same, except that the language should be specified as
|
||||||
|
<literal>plperlu</>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The body of the function is ordinary Perl code. Arguments and
|
||||||
|
results are handled as in any other Perl subroutine: arguments
|
||||||
|
are passed in <varname>@_</varname>, and a result value is returned
|
||||||
|
with <literal>return</> or as the last expression evaluated in the
|
||||||
|
function. For example, a function
|
||||||
|
returning the greater of two integer values could be defined as:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS '
|
||||||
|
if ($_[0] > $_[1]) { return $_[0]; }
|
||||||
|
return $_[1];
|
||||||
|
' LANGUAGE plperl;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
If a NULL is passed to a function, the argument value will appear
|
||||||
|
as <quote>undefined</> in Perl. The above function definition will
|
||||||
|
not behave very nicely with NULL inputs (in fact, it will act as
|
||||||
|
though they are zeroes). We could add <literal>WITH (isStrict)</>
|
||||||
|
to the function definition to make <productname>PostgreSQL</productname>
|
||||||
|
do something more reasonable: if a NULL is passed, the
|
||||||
|
function will not be called at all, but will just return a NULL
|
||||||
|
result automatically. Alternatively, we could check for undefined
|
||||||
|
inputs in the function body. For example, suppose that we wanted perl_max
|
||||||
|
with one null and one non-null argument to return the non-null
|
||||||
|
argument, rather than NULL:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS '
|
||||||
|
my ($a,$b) = @_;
|
||||||
|
if (! defined $a) {
|
||||||
|
if (! defined $b) { return undef; }
|
||||||
|
return $b;
|
||||||
|
}
|
||||||
|
if (! defined $b) { return $a; }
|
||||||
|
if ($a > $b) { return $a; }
|
||||||
|
return $b;
|
||||||
|
' LANGUAGE plperl;
|
||||||
|
</programlisting>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
As shown above,
|
||||||
|
to return a NULL from a PL/Perl function, return an undefined
|
||||||
|
value. This can be done whether the function is strict or not.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Composite-type arguments are passed to the function as references to
|
||||||
|
hashes. The keys of the hash are the attribute names of the composite
|
||||||
|
type. Here is an example:
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
CREATE TABLE employee (
|
CREATE TABLE employee (
|
||||||
name text,
|
name text,
|
||||||
basesalary integer,
|
basesalary integer,
|
||||||
bonus integer
|
bonus integer
|
||||||
);
|
);
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
In order to get the total compensation (base + bonus) we could
|
|
||||||
define a function as follows:
|
|
||||||
<programlisting>
|
|
||||||
CREATE FUNCTION totalcomp(integer, integer) RETURNS integer
|
|
||||||
AS 'return $_[0] + $_[1]'
|
|
||||||
LANGUAGE plperl;
|
|
||||||
</programlisting>
|
|
||||||
|
|
||||||
Notice that the arguments to the function are passed in
|
|
||||||
<varname>@_</varname> as might be expected.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
We can now use our function like so:
|
|
||||||
<programlisting>
|
|
||||||
SELECT name, totalcomp(basesalary, bonus) FROM employee;
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
But, we can also pass entire tuples to our functions:
|
|
||||||
<programlisting>
|
|
||||||
CREATE FUNCTION empcomp(employee) RETURNS integer AS '
|
CREATE FUNCTION empcomp(employee) RETURNS integer AS '
|
||||||
my $emp = shift;
|
my ($emp) = @_;
|
||||||
return $emp->{''basesalary''} + $emp->{''bonus''};
|
return $emp->{''basesalary''} + $emp->{''bonus''};
|
||||||
' LANGUAGE plperl;
|
' LANGUAGE plperl;
|
||||||
</programlisting>
|
|
||||||
A tuple is passed as a reference to a hash. The keys are the names
|
SELECT name, empcomp(employee) FROM employee;
|
||||||
of the fields in the tuples. The hash values are values of the
|
</programlisting>
|
||||||
corresponding fields in the tuple.
|
</para>
|
||||||
</para>
|
|
||||||
|
<para>
|
||||||
|
There is not currently any support for returning a composite-type
|
||||||
|
result value.
|
||||||
|
</para>
|
||||||
|
|
||||||
<tip>
|
<tip>
|
||||||
<para>
|
<para>
|
||||||
Because the function body is passed as an SQL string literal to
|
Because the function body is passed as an SQL string literal to
|
||||||
<command>CREATE FUNCTION</command> you have to escape single
|
<command>CREATE FUNCTION</command>, you have to escape single
|
||||||
quotes within your Perl source, either by doubling them as shown
|
quotes and backslashes within your Perl source, typically by doubling them
|
||||||
above, or by using the extended quoting functions
|
as shown in the above example. Another possible approach is to
|
||||||
|
avoid writing single quotes by using Perl's extended quoting functions
|
||||||
(<literal>q[]</literal>, <literal>qq[]</literal>,
|
(<literal>q[]</literal>, <literal>qq[]</literal>,
|
||||||
<literal>qw[]</literal>). Backslashes must be escaped by doubling
|
<literal>qw[]</literal>).
|
||||||
them.
|
|
||||||
</para>
|
</para>
|
||||||
</tip>
|
</tip>
|
||||||
|
|
||||||
<para>
|
|
||||||
The new function <function>empcomp</function> can be used like:
|
|
||||||
<programlisting>
|
|
||||||
SELECT name, empcomp(employee) FROM employee;
|
|
||||||
</programlisting>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Here is an example of a function that will not work because file
|
Here is an example of a function that will not work because file
|
||||||
system operations are not allowed for security reasons:
|
system operations are not allowed for security reasons:
|
||||||
@ -174,9 +232,29 @@ CREATE FUNCTION badfunc() RETURNS integer AS '
|
|||||||
The creation of the function will succeed, but executing it will not.
|
The creation of the function will succeed, but executing it will not.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Note that if same function was created by superuser using language
|
Note that if the same function was created by a superuser using language
|
||||||
<literal>plperlu</>, execution would succeed.
|
<literal>plperlu</>, execution would succeed.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Data Values in PL/Perl</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The argument values supplied to a PL/Perl function's script are simply
|
||||||
|
the input arguments converted to text form (just as if they had been
|
||||||
|
displayed by a SELECT statement). Conversely, the <literal>return</>
|
||||||
|
command will accept any string that is acceptable input format for
|
||||||
|
the function's declared return type. So, the PL/Perl programmer can
|
||||||
|
manipulate data values as if they were just text.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Database Access from PL/Perl</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Access to the database itself from your Perl function can be done via
|
Access to the database itself from your Perl function can be done via
|
||||||
an experimental module <ulink
|
an experimental module <ulink
|
||||||
@ -188,8 +266,55 @@ CREATE FUNCTION badfunc() RETURNS integer AS '
|
|||||||
with normal <acronym>DBI</> syntax.
|
with normal <acronym>DBI</> syntax.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
</sect1>
|
<para>
|
||||||
</chapter>
|
PL/Perl itself presently provides only one additional Perl command:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<indexterm>
|
||||||
|
<primary>elog</primary>
|
||||||
|
</indexterm>
|
||||||
|
<term><function>elog</> <replaceable>level</replaceable>, <replaceable>msg</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Emit a log or error message. Possible levels are <literal>DEBUG</>,
|
||||||
|
<literal>NOTICE</>, and <literal>ERROR</>.
|
||||||
|
<literal>DEBUG</> and <literal>NOTICE</> simply emit the given message
|
||||||
|
into the postmaster log (and send it to the client too, in the case of
|
||||||
|
<literal>NOTICE</>). <literal>ERROR</> raises an error condition:
|
||||||
|
further execution of the function is abandoned, and the current
|
||||||
|
transaction is aborted.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
<sect2>
|
||||||
|
<title>Missing Features</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
PL/Perl functions cannot call each other directly (because they
|
||||||
|
are anonymous subroutines inside Perl). There's presently
|
||||||
|
no way for them to share global variables, either.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
PL/Perl cannot currently be used to write trigger functions.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
DBD::PgSPI or similar capability should be integrated
|
||||||
|
into the standard <productname>PostgreSQL</productname> distribution.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</sect2>
|
||||||
|
|
||||||
|
</sect1>
|
||||||
|
</chapter>
|
||||||
|
|
||||||
<!-- Keep this comment at the end of the file
|
<!-- Keep this comment at the end of the file
|
||||||
Local variables:
|
Local variables:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user