Commit 467f43d2 authored by Tom Lane's avatar Tom Lane

Document PL/TclU language variant, and do some minor copy-editing.

parent 1f78ad26
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.7 2001/02/09 03:06:38 tgl Exp $
--> -->
<chapter id="pltcl"> <chapter id="pltcl">
...@@ -9,7 +9,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere ...@@ -9,7 +9,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
PL/Tcl is a loadable procedural language for the PL/Tcl is a loadable procedural language for the
<productname>Postgres</productname> database system <productname>Postgres</productname> database system
that enables the Tcl language to be used to create functions and that enables the Tcl language to be used to create functions and
trigger-procedures. trigger procedures.
</para> </para>
<para> <para>
...@@ -26,24 +26,39 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere ...@@ -26,24 +26,39 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
writer has in the C language, except for some restrictions. writer has in the C language, except for some restrictions.
</para> </para>
<para> <para>
The good restriction is, that everything is executed in a safe The good restriction is that everything is executed in a safe
Tcl-interpreter. In addition to the limited command set of safe Tcl, only Tcl interpreter. In addition to the limited command set of safe Tcl, only
a few commands are available to access the database over SPI and to raise a few commands are available to access the database via SPI and to raise
messages via elog(). There is no way to access internals of the messages via elog(). There is no way to access internals of the
database backend or gaining OS-level access under the permissions of the database backend or to gain OS-level access under the permissions of the
<productname>Postgres</productname> user ID like in C. <productname>Postgres</productname> user ID, as a C function can do.
Thus, any unprivileged database user may be Thus, any unprivileged database user may be
permitted to use this language. permitted to use this language.
</para> </para>
<para> <para>
The other, internal given, restriction is, that Tcl procedures cannot The other, implementation restriction is that Tcl procedures cannot
be used to create input-/output-functions for new data types. be used to create input/output functions for new data types.
</para> </para>
<para> <para>
The shared object for the PL/Tcl call handler is automatically built Sometimes it is desirable to write Tcl functions that are not restricted
and installed in the <productname>Postgres</productname> to safe Tcl --- for example, one might want a Tcl function that sends
library directory if the Tcl/Tk support is specified mail. To handle these cases, there is a variant of PL/Tcl called PL/TclU
in the configuration step of the installation procedure. (for untrusted Tcl). This is the exact same language except that a full
Tcl interpreter is used. <emphasis>If PL/TclU is used, it must be
installed as an untrusted procedural language</emphasis> so that only
database superusers can create functions in it. The writer of a PL/TclU
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.
</para>
<para>
The shared object for the PL/Tcl and PL/TclU call handlers is
automatically built and installed in the
<productname>Postgres</productname>
library directory if Tcl/Tk support is specified
in the configuration step of the installation procedure. To install
PL/Tcl and/or PL/TclU in a particular database, use the
<filename>createlang</filename> script.
</para> </para>
</sect1> </sect1>
...@@ -61,7 +76,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere ...@@ -61,7 +76,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
different functions as long as the number of arguments or their types different functions as long as the number of arguments or their types
differ. This would collide with Tcl procedure names. To offer the same differ. This would collide with Tcl procedure names. To offer the same
flexibility in PL/Tcl, the internal Tcl procedure names contain the object flexibility in PL/Tcl, the internal Tcl procedure names contain the object
ID of the procedures pg_proc row as part of their name. Thus, different ID of the procedure's pg_proc row as part of their name. Thus, different
argtype versions of the same <productname>Postgres</productname> argtype versions of the same <productname>Postgres</productname>
function are different for Tcl too. function are different for Tcl too.
</para> </para>
...@@ -72,17 +87,18 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere ...@@ -72,17 +87,18 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
<title>Defining Functions in PL/Tcl</title> <title>Defining Functions in PL/Tcl</title>
<para> <para>
To create a function in the PL/Tcl language, use the known syntax To create a function in the PL/Tcl language, use the standard syntax
<programlisting> <programlisting>
CREATE FUNCTION <replaceable>funcname</replaceable> <replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS ' CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS '
# PL/Tcl function body # PL/Tcl function body
' LANGUAGE 'pltcl'; ' LANGUAGE 'pltcl';
</programlisting> </programlisting>
When calling this function in a query, the arguments are given as When the function is called, the arguments are given as
variables $1 ... $n to the Tcl procedure body. So a little max function variables $1 ... $n to the Tcl procedure body. For example,
returning the higher of two int4 values would be created as: a function
returning the higher of two int4 values could be defined as:
<programlisting> <programlisting>
CREATE FUNCTION tcl_max (int4, int4) RETURNS int4 AS ' CREATE FUNCTION tcl_max (int4, int4) RETURNS int4 AS '
...@@ -120,13 +136,18 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS ' ...@@ -120,13 +136,18 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
<para> <para>
Sometimes (especially when using the SPI functions described later) it Sometimes (especially when using the SPI functions described later) it
is useful to have some global status data that is held between two is useful to have some global status data that is held between two
calls to a procedure. calls to a procedure. This is easily done since
All PL/Tcl procedures executed in one backend share the same all PL/Tcl procedures executed in one backend share the same
safe Tcl interpreter. safe Tcl interpreter.
To help protecting PL/Tcl procedures from side effects, </para>
<para>
To help protect PL/Tcl procedures from unwanted side effects,
an array is made available to each procedure via the upvar an array is made available to each procedure via the upvar
command. The global name of this variable is the procedures internal command. The global name of this variable is the procedure's internal
name and the local name is GD. name and the local name is GD. It is recommended that GD be used
for private status data of a procedure. Use regular Tcl global variables
only for values that you specifically intend to be shared among multiple
procedures.
</para> </para>
</sect2> </sect2>
...@@ -140,7 +161,7 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS ' ...@@ -140,7 +161,7 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
language. language.
</para> </para>
<para> <para>
The informations from the trigger manager are given to the procedure body The information from the trigger manager is given to the procedure body
in the following variables: in the following variables:
<variablelist> <variablelist>
...@@ -259,8 +280,8 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS ' ...@@ -259,8 +280,8 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
</para> </para>
<para> <para>
Here's a little example trigger procedure that forces an integer value Here's a little example trigger procedure that forces an integer value
in a table to keep track of the # of updates that are performed on the in a table to keep track of the number of updates that are performed on the
row. For new row's inserted, the value is initialized to 0 and then row. For new rows inserted, the value is initialized to 0 and then
incremented on every update operation: incremented on every update operation:
<programlisting> <programlisting>
...@@ -305,7 +326,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab ...@@ -305,7 +326,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
<para> <para>
Fire a log message. Possible levels are NOTICE, ERROR, Fire a log message. Possible levels are NOTICE, ERROR,
FATAL, DEBUG and NOIND FATAL, DEBUG and NOIND
like for the <function>elog</function> C function. as for the <function>elog</function> C function.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -332,7 +353,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab ...@@ -332,7 +353,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
"SELECT 'doesn't' AS ret" "SELECT 'doesn't' AS ret"
</programlisting> </programlisting>
what would cause a parse error during which would cause a parse error during
<function>spi_exec</function> or <function>spi_exec</function> or
<function>spi_prepare</function>. <function>spi_prepare</function>.
It should contain It should contain
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment