<!-- doc/src/sgml/pltcl.sgml -->
<chapter id="pltcl">
<title>PL/Tcl — Tcl Procedural Language</title>
<indexterm zone="pltcl">
<primary>PL/Tcl</primary>
</indexterm>
<indexterm zone="pltcl">
<primary>Tcl</primary>
</indexterm>
<para>
PL/Tcl is a loadable procedural language for the
<productname>PostgreSQL</productname> database system
that enables the <ulink url="https://www.tcl.tk/">
Tcl language</ulink> to be used to write
<productname>PostgreSQL</productname> functions and procedures.
</para>
<!-- **** PL/Tcl overview **** -->
<sect1 id="pltcl-overview">
<title>Overview</title>
<para>
PL/Tcl offers most of the capabilities a function writer has in
the C language, with a few restrictions, and with the addition of
the powerful string processing libraries that are available for
Tcl.
</para>
<para>
One compelling <emphasis>good</emphasis> restriction is that
everything is executed from within the safety of the context of a
Tcl interpreter. In addition to the limited command set of safe
Tcl, only a few commands are available to access the database via
SPI and to raise messages via <function>elog()</function>. PL/Tcl
provides no way to access internals of the database server or to
gain OS-level access under the permissions of the
<productname>PostgreSQL</productname> server process, as a C
function can do. Thus, unprivileged database users can be trusted
to use this language; it does not give them unlimited authority.
</para>
<para>
The other notable implementation restriction is that Tcl functions
cannot be used to create input/output functions for new data
types.
</para>
<para>
Sometimes it is desirable to write Tcl functions that are not restricted
to safe Tcl. For example, one might want a Tcl function that sends
email. To handle these cases, there is a variant of <application>PL/Tcl</application> called <literal>PL/TclU</literal>
(for untrusted Tcl). This is exactly the same language except that a full
Tcl interpreter is used. <emphasis>If <application>PL/TclU</application> 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 <application>PL/TclU</application>
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 code for the <application>PL/Tcl</application> and
<application>PL/TclU</application> call handlers is automatically built and
installed in the <productname>PostgreSQL</productname> library
directory if Tcl support is specified in the configuration step of
the installation procedure. To install <application>PL/Tcl</application>
and/or <application>PL/TclU</application> in a particular database, use the
<command>CREATE EXTENSION</command> command, for example
<literal>CREATE EXTENSION pltcl</literal> or
<literal>CREATE EXTENSION pltclu</literal>.
</para>
</sect1>
<!-- **** PL/Tcl description **** -->
<sect1 id="pltcl-functions">
<title>PL/Tcl Functions and Arguments</title>
<para>
To create a function in the <application>PL/Tcl</application> language, use
the standard <xref linkend="sql-createfunction"/> syntax:
<programlisting>
CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS $$
# PL/Tcl function body
$$ LANGUAGE pltcl;
</programlisting>
<application>PL/TclU</application> is the same, except that the language has to be specified as
<literal>pltclu</literal>.
</para>
<para>
The body of the function is simply a piece of Tcl script.
When the function is called, the