mirror of
https://github.com/postgres/postgres.git
synced 2025-07-20 05:03:10 +03:00
201 lines
6.2 KiB
Plaintext
201 lines
6.2 KiB
Plaintext
<!--
|
|
$Header: /cvsroot/pgsql/doc/src/sgml/plperl.sgml,v 2.9 2001/06/22 21:37:14 momjian Exp $
|
|
-->
|
|
|
|
<chapter id="plperl">
|
|
<title>PL/Perl - Perl Procedural Language</title>
|
|
|
|
<indexterm zone="plperl">
|
|
<primary>PL/Perl</primary>
|
|
</indexterm>
|
|
|
|
<indexterm zone="plperl">
|
|
<primary>Perl</primary>
|
|
</indexterm>
|
|
|
|
<para>
|
|
PL/Perl allows you to write functions in the Perl programming
|
|
language that may be used in SQL queries as if they were built into
|
|
<productname>Postgres</productname>.
|
|
</para>
|
|
|
|
<para>
|
|
The PL/Perl interpreter (when installed as trusted interpreter with
|
|
default name 'plperl') intepreter 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 filehandle
|
|
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>
|
|
When PL/Perl is installed as 'untrusted' interpreter (with name 'plperlu'),
|
|
everything is permitted, and any perl code can be loaded (by superuser only).
|
|
</para>
|
|
|
|
<sect1 id="plperl-install">
|
|
<title>Building and Installing</title>
|
|
|
|
<para>
|
|
In order to build and install PL/Perl if you are installing
|
|
<productname>Postgres</productname> from source then the
|
|
<option>--with-perl</option> must be supplied to the
|
|
<indexterm><primary><filename>configure</filename></primary></indexterm>
|
|
<filename>configure</filename> script. PL/Perl requires that, when
|
|
<productname>Perl</productname> was installed, the
|
|
<indexterm><primary>libperl</primary></indexterm>
|
|
<filename>libperl</filename> library was build as a shared object.
|
|
At the time of this writing, this is almost never the case in the
|
|
Perl packages that are distributed with the operating systems. A
|
|
message like this will appear during the build to point out this
|
|
fact:
|
|
<screen>
|
|
<computeroutput>
|
|
*****
|
|
* Cannot build PL/Perl because libperl is not a shared library.
|
|
* Skipped.
|
|
*****
|
|
</computeroutput>
|
|
</screen>
|
|
Therefore it is likely that you will have to re-build and install
|
|
<productname>Perl</productname> manually to be able to build
|
|
PL/Perl.
|
|
</para>
|
|
|
|
<para>
|
|
When you want to retry to build PL/Perl after having reinstalled
|
|
Perl, then change to the directory
|
|
<filename>src/pl/plperl</filename> in the
|
|
<productname>Postgres</productname> source tree and issue the commands
|
|
<programlisting>
|
|
gmake clean
|
|
gmake all
|
|
gmake install
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>
|
|
The <command>createlang</command> command is used to install the
|
|
language into a database.
|
|
<screen>
|
|
<prompt>$</prompt> <userinput>createlang plperl template1</userinput>
|
|
</screen>
|
|
Alternatively, to create untrusted interpreter (where functions can only
|
|
be created by 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">
|
|
<title>Using PL/Perl</title>
|
|
|
|
<para>
|
|
Assume you have the following table:
|
|
<programlisting>
|
|
CREATE TABLE EMPLOYEE (
|
|
name text,
|
|
basesalary 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 '
|
|
my $emp = shift;
|
|
return $emp->{''basesalary''} + $emp->{''bonus''};
|
|
' LANGUAGE 'plperl';
|
|
</programlisting>
|
|
A tuple is passed as a reference to a hash. The keys are the names
|
|
of the fields in the tuples. The hash values are values of the
|
|
corresponding fields in the tuple.
|
|
</para>
|
|
|
|
<tip>
|
|
<para>
|
|
Because the function body is passed as an SQL string literal to
|
|
<command>CREATE FUNCTION</command> you have to escape single
|
|
quotes within your Perl source, either by doubling them as shown
|
|
above, or by using the extended quoting functions
|
|
(<literal>q[]</literal>, <literal>qq[]</literal>,
|
|
<literal>qw[]</literal>). Backslashes must be escaped by doubling
|
|
them.
|
|
</para>
|
|
</tip>
|
|
|
|
<para>
|
|
The new function <function>empcomp</function> can used like:
|
|
<programlisting>
|
|
SELECT name, empcomp(employee) FROM employee;
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>
|
|
Here is an example of a function that will not work because file
|
|
system operations are not allowed for security reasons:
|
|
<programlisting>
|
|
CREATE FUNCTION badfunc() RETURNS integer AS '
|
|
open(TEMP, ">/tmp/badfile");
|
|
print TEMP "Gotcha!\n";
|
|
return 1;
|
|
' LANGUAGE 'plperl';
|
|
</programlisting>
|
|
The creation of the function will succeed, but executing it will not.
|
|
|
|
Note that if same function was created by superuser using language
|
|
'plperlu', execution would succeed.
|
|
</para>
|
|
<para>
|
|
Access to database itself from your perl function can be done via
|
|
an experimental module DBD::PgSPI, available at <ulink url="http://www.formenos.org/PgSPI/">this site</ulink>. This module makes available a DBI-compliant
|
|
database-handle named $pg_dbh, and you can use that to make queries with
|
|
normal DBI syntax.
|
|
</para>
|
|
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode:sgml
|
|
sgml-omittag:nil
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"./reference.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:("/usr/lib/sgml/catalog")
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
-->
|