head	2.50;
access;
symbols
	REL9_0_0:2.50
	REL9_1_ALPHA1:2.50
	REL9_0_RC1:2.50
	REL9_0_BETA4:2.50
	REL9_0_STABLE:2.50.0.2
	REL9_0_BETA3:2.50
	REL9_0_BETA2:2.50
	REL7_4_29:2.26.2.3
	REL8_0_25:2.33.4.2
	REL8_1_21:2.38.2.2
	REL8_2_17:2.42.2.2
	REL8_3_11:2.47.2.1
	REL8_4_4:2.48.2.1
	REL9_0_BETA1:2.49
	REL9_0_ALPHA5_BRANCH:2.48.0.12
	REL9_0_ALPHA5:2.48
	REL7_4_28:2.26.2.2
	REL8_0_24:2.33.4.1
	REL8_1_20:2.38.2.1
	REL8_2_16:2.42.2.1
	REL8_3_10:2.47
	REL8_4_3:2.48
	REL9_0_ALPHA4:2.48
	REL9_0_ALPHA4_BRANCH:2.48.0.10
	REL8_5_ALPHA3:2.48
	REL8_5_ALPHA3_BRANCH:2.48.0.8
	REL7_4_27:2.26.2.2
	REL8_0_23:2.33.4.1
	REL8_1_19:2.38.2.1
	REL8_2_15:2.42.2.1
	REL8_3_9:2.47
	REL8_4_2:2.48
	REL8_5_ALPHA2:2.48
	REL8_5_ALPHA2_BRANCH:2.48.0.6
	REL7_4_26:2.26.2.2
	REL8_0_22:2.33.4.1
	REL8_1_18:2.38.2.1
	REL8_2_14:2.42.2.1
	REL8_3_8:2.47
	REL8_4_1:2.48
	REL8_5_ALPHA1:2.48
	REL8_5_ALPHA1_BRANCH:2.48.0.4
	REL8_4_STABLE:2.48.0.2
	REL8_4_0:2.48
	REL8_4_RC2:2.48
	REL8_4_RC1:2.48
	REL8_4_BETA2:2.48
	REL8_4_BETA1:2.48
	REL7_4_25:2.26.2.2
	REL8_0_21:2.33.4.1
	REL8_1_17:2.38.2.1
	REL8_2_13:2.42.2.1
	REL8_3_7:2.47
	REL7_4_24:2.26.2.2
	REL8_0_20:2.33.4.1
	REL8_1_16:2.38.2.1
	REL8_2_12:2.42.2.1
	REL8_3_6:2.47
	REL7_4_23:2.26.2.2
	REL8_0_19:2.33.4.1
	REL8_1_15:2.38.2.1
	REL8_2_11:2.42.2.1
	REL8_3_5:2.47
	REL7_4_22:2.26.2.2
	REL8_0_18:2.33.4.1
	REL8_1_14:2.38.2.1
	REL8_2_10:2.42.2.1
	REL8_3_4:2.47
	REL7_4_21:2.26.2.2
	REL8_0_17:2.33.4.1
	REL8_1_13:2.38.2.1
	REL8_2_9:2.42.2.1
	REL8_3_3:2.47
	REL7_4_20:2.26.2.2
	REL8_0_16:2.33.4.1
	REL8_1_12:2.38.2.1
	REL8_2_8:2.42.2.1
	REL8_3_2:2.47
	REL8_2_7:2.42.2.1
	REL8_3_1:2.47
	REL8_3_STABLE:2.47.0.2
	REL8_3_0:2.47
	REL8_3_RC2:2.47
	REL7_3_21:2.22
	REL7_4_19:2.26.2.2
	REL8_0_15:2.33.4.1
	REL8_1_11:2.38.2.1
	REL8_2_6:2.42.2.1
	REL8_3_RC1:2.47
	REL8_3_BETA4:2.46
	REL8_3_BETA3:2.46
	REL8_3_BETA2:2.46
	REL8_3_BETA1:2.46
	REL7_3_20:2.22
	REL7_4_18:2.26.2.2
	REL8_0_14:2.33.4.1
	REL8_1_10:2.38.2.1
	REL8_2_5:2.42.2.1
	REL7_3_19:2.22
	REL7_4_17:2.26.2.2
	REL8_0_13:2.33.4.1
	REL8_1_9:2.38.2.1
	REL8_2_4:2.42.2.1
	REL8_0_12:2.33.4.1
	REL8_1_8:2.38.2.1
	REL8_2_3:2.42.2.1
	REL7_3_18:2.22
	REL7_4_16:2.26.2.2
	REL8_0_11:2.33.4.1
	REL8_1_7:2.38.2.1
	REL8_2_2:2.42.2.1
	REL8_0_10:2.33.4.1
	REL8_1_6:2.38.2.1
	REL8_2_1:2.42
	REL7_4_15:2.26.2.2
	REL7_3_17:2.22
	REL8_2_STABLE:2.42.0.2
	REL8_2_0:2.42
	REL8_2_RC1:2.42
	REL8_2_BETA3:2.42
	REL8_2_BETA2:2.42
	REL8_1_5:2.38.2.1
	REL8_0_9:2.33.4.1
	REL7_4_14:2.26.2.2
	REL7_3_16:2.22
	REL8_2_BETA1:2.42
	REL7_3_15:2.22
	REL7_4_13:2.26.2.2
	REL8_0_8:2.33.4.1
	REL8_1_4:2.38
	REL7_3_14:2.22
	REL7_4_12:2.26.2.2
	REL8_0_7:2.33.4.1
	REL8_1_3:2.38
	REL7_3_13:2.22
	REL7_4_11:2.26.2.2
	REL8_0_6:2.33.4.1
	REL8_1_2:2.38
	REL7_3_12:2.22
	REL7_4_10:2.26.2.2
	REL8_0_5:2.33.4.1
	REL8_1_1:2.38
	REL8_1_STABLE:2.38.0.2
	REL8_1_0:2.38
	REL8_1_0RC1:2.38
	REL8_1_0BETA4:2.38
	REL8_1_0BETA3:2.38
	REL7_3_11:2.22
	REL7_4_9:2.26.2.2
	REL8_0_4:2.33.4.1
	REL8_1_0BETA2:2.38
	REL8_1_0BETA1:2.38
	REL7_2_8:2.18
	REL7_3_10:2.22
	REL7_4_8:2.26.2.2
	REL8_0_3:2.33.4.1
	REL8_0_2:2.33.4.1
	REL7_2_7:2.18
	REL7_3_9:2.22
	REL7_4_7:2.26.2.2
	REL8_0_1:2.33.4.1
	REL8_0_STABLE:2.33.0.4
	REL8_0_0:2.33.0.2
	REL8_0_0RC5:2.33
	REL8_0_0RC4:2.33
	REL8_0_0RC3:2.33
	REL8_0_0RC2:2.32
	REL8_0_0RC1:2.32
	REL8_0_0BETA5:2.32
	REL8_0_0BETA4:2.31
	REL7_4_6:2.26.2.2
	REL7_3_8:2.22
	REL7_2_6:2.18
	REL8_0_0BETA3:2.31
	REL8_0_0BETA2:2.30
	REL7_2_5:2.18
	REL7_4_5:2.26.2.2
	REL7_3_7:2.22
	REL7_4_4:2.26.2.2
	REL8_0_0BETA1:2.30
	REL7_4_3:2.26.2.2
	REL7_4_2:2.26.2.2
	REL7_3_6:2.22
	REL7_4_1:2.26.2.1
	REL7_3_5:2.22
	REL7_4:2.26.2.1
	REL7_4_RC2:2.26
	REL7_4_STABLE:2.26.0.2
	REL7_4_RC1:2.26
	REL7_4_BETA5:2.26
	REL7_4_BETA4:2.26
	REL7_4_BETA3:2.26
	REL7_4_BETA2:2.24
	WIN32_DEV:2.24.0.2
	REL7_4_BETA1:2.24
	REL7_3_4:2.22
	REL7_3_2:2.22
	REL7_2_4:2.18
	REL7_3_STABLE:2.22.0.2
	REL7_2_3:2.18
	REL7_2_STABLE:2.18.0.2
	REL7_2:2.18
	REL7_2_RC2:2.18
	REL7_2_RC1:2.17
	REL7_2_BETA5:2.17
	REL7_2_BETA4:2.17
	REL7_2_BETA3:2.16
	REL7_2_BETA2:2.15
	REL7_2_BETA1:2.15
	REL7_1_2:2.9
	REL7_1_STABLE:2.9.0.2
	REL7_1_BETA:2.6
	REL7_1_BETA3:2.6
	REL7_1_BETA2:2.6
	REL7_1:2.8
	REL7_0_PATCHES:2.4.0.2
	REL7_0:2.3;
locks; strict;
comment	@# @;


2.50
date	2010.05.13.18.29.12;	author tgl;	state Exp;
branches;
next	2.49;

2.49
date	2010.04.03.07.22.55;	author petere;	state Exp;
branches;
next	2.48;

2.48
date	2008.03.28.00.21.55;	author tgl;	state Exp;
branches
	2.48.2.1;
next	2.47;

2.47
date	2007.12.03.23.49.50;	author tgl;	state Exp;
branches
	2.47.2.1;
next	2.46;

2.46
date	2007.02.21.03.27.31;	author adunstan;	state Exp;
branches;
next	2.45;

2.45
date	2007.02.01.00.28.17;	author momjian;	state Exp;
branches;
next	2.44;

2.44
date	2007.01.31.20.56.18;	author momjian;	state Exp;
branches;
next	2.43;

2.43
date	2007.01.30.22.29.23;	author momjian;	state Exp;
branches;
next	2.42;

2.42
date	2006.09.16.00.30.15;	author momjian;	state Exp;
branches
	2.42.2.1;
next	2.41;

2.41
date	2006.05.30.11.40.21;	author momjian;	state Exp;
branches;
next	2.40;

2.40
date	2006.05.27.20.24.16;	author adunstan;	state Exp;
branches;
next	2.39;

2.39
date	2006.03.10.19.10.48;	author momjian;	state Exp;
branches;
next	2.38;

2.38
date	2005.05.20.01.52.25;	author neilc;	state Exp;
branches
	2.38.2.1;
next	2.37;

2.37
date	2005.04.09.03.52.43;	author momjian;	state Exp;
branches;
next	2.36;

2.36
date	2005.03.31.03.54.38;	author momjian;	state Exp;
branches;
next	2.35;

2.35
date	2005.03.13.09.36.30;	author neilc;	state Exp;
branches;
next	2.34;

2.34
date	2005.01.22.22.56.36;	author momjian;	state Exp;
branches;
next	2.33;

2.33
date	2004.12.30.21.45.37;	author tgl;	state Exp;
branches
	2.33.4.1;
next	2.32;

2.32
date	2004.11.21.21.17.02;	author tgl;	state Exp;
branches;
next	2.31;

2.31
date	2004.09.20.22.48.25;	author tgl;	state Exp;
branches;
next	2.30;

2.30
date	2004.05.16.23.22.07;	author neilc;	state Exp;
branches;
next	2.29;

2.29
date	2004.01.24.23.06.29;	author tgl;	state Exp;
branches;
next	2.28;

2.28
date	2003.11.29.19.51.37;	author pgsql;	state Exp;
branches;
next	2.27;

2.27
date	2003.11.12.22.47.47;	author petere;	state Exp;
branches;
next	2.26;

2.26
date	2003.09.08.23.02.28;	author petere;	state Exp;
branches
	2.26.2.1;
next	2.25;

2.25
date	2003.08.31.17.32.19;	author petere;	state Exp;
branches;
next	2.24;

2.24
date	2003.06.22.16.17.00;	author tgl;	state Exp;
branches
	2.24.2.1;
next	2.23;

2.23
date	2003.04.07.01.29.25;	author petere;	state Exp;
branches;
next	2.22;

2.22
date	2002.09.21.18.32.53;	author petere;	state Exp;
branches;
next	2.21;

2.21
date	2002.08.22.00.01.40;	author tgl;	state Exp;
branches;
next	2.20;

2.20
date	2002.03.22.19.20.21;	author petere;	state Exp;
branches;
next	2.19;

2.19
date	2002.03.06.19.05.58;	author momjian;	state Exp;
branches;
next	2.18;

2.18
date	2002.01.23.21.08.17;	author tgl;	state Exp;
branches;
next	2.17;

2.17
date	2001.11.21.05.53.41;	author thomas;	state Exp;
branches;
next	2.16;

2.16
date	2001.11.19.03.58.24;	author tgl;	state Exp;
branches;
next	2.15;

2.15
date	2001.10.13.04.23.50;	author momjian;	state Exp;
branches;
next	2.14;

2.14
date	2001.09.13.15.55.23;	author petere;	state Exp;
branches;
next	2.13;

2.13
date	2001.09.10.21.58.47;	author petere;	state Exp;
branches;
next	2.12;

2.12
date	2001.08.02.15.45.55;	author momjian;	state Exp;
branches;
next	2.11;

2.11
date	2001.06.09.02.19.07;	author tgl;	state Exp;
branches;
next	2.10;

2.10
date	2001.05.12.22.51.35;	author petere;	state Exp;
branches;
next	2.9;

2.9
date	2001.04.30.22.22.34;	author tgl;	state Exp;
branches;
next	2.8;

2.8
date	2001.03.25.10.16.12;	author petere;	state Exp;
branches;
next	2.7;

2.7
date	2001.02.09.03.06.38;	author tgl;	state Exp;
branches;
next	2.6;

2.6
date	2000.09.29.20.21.34;	author petere;	state Exp;
branches;
next	2.5;

2.5
date	2000.08.25.15.17.36;	author thomas;	state Exp;
branches;
next	2.4;

2.4
date	2000.05.18.14.24.32;	author momjian;	state Exp;
branches;
next	2.3;

2.3
date	2000.03.31.06.17.21;	author thomas;	state Exp;
branches;
next	2.2;

2.2
date	2000.03.31.03.27.41;	author thomas;	state Exp;
branches;
next	2.1;

2.1
date	2000.03.30.22.13.30;	author thomas;	state Exp;
branches;
next	;

2.24.2.1
date	2003.09.07.04.36.43;	author momjian;	state Exp;
branches;
next	;

2.26.2.1
date	2003.11.12.20.05.14;	author petere;	state Exp;
branches;
next	2.26.2.2;

2.26.2.2
date	2004.01.24.23.06.41;	author tgl;	state Exp;
branches;
next	2.26.2.3;

2.26.2.3
date	2010.05.13.18.29.54;	author tgl;	state Exp;
branches;
next	;

2.33.4.1
date	2005.01.22.23.05.48;	author momjian;	state Exp;
branches;
next	2.33.4.2;

2.33.4.2
date	2010.05.13.18.29.45;	author tgl;	state Exp;
branches;
next	;

2.38.2.1
date	2006.05.30.12.32.37;	author momjian;	state Exp;
branches;
next	2.38.2.2;

2.38.2.2
date	2010.05.13.18.29.37;	author tgl;	state Exp;
branches;
next	;

2.42.2.1
date	2007.01.30.22.29.40;	author momjian;	state Exp;
branches;
next	2.42.2.2;

2.42.2.2
date	2010.05.13.18.29.31;	author tgl;	state Exp;
branches;
next	;

2.47.2.1
date	2010.05.13.18.29.25;	author tgl;	state Exp;
branches;
next	;

2.48.2.1
date	2010.05.13.18.29.19;	author tgl;	state Exp;
branches;
next	;


desc
@@


2.50
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.49 2010/04/03 07:22:55 petere Exp $ -->

 <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="http://www.tcl.tk/">
   Tcl language</ulink> to be used to write functions and
   trigger 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()</>.  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</> called <literal>PL/TclU</>
    (for untrusted Tcl).  This is the exact same language except that a full
    Tcl interpreter is used.  <emphasis>If <application>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 <application>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 code for the <application>PL/Tcl</> and
    <application>PL/TclU</> 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</>
    and/or <application>PL/TclU</> in a particular database, use the
    <command>createlang</command> program, for example
    <literal>createlang pltcl <replaceable>dbname</></literal> or
    <literal>createlang pltclu <replaceable>dbname</></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</> 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</> is the same, except that the language has to be specified as
     <literal>pltclu</>.
    </para>

    <para>
     The body of the function is simply a piece of Tcl script.
     When the function is called, the argument values are passed as
     variables <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal> to the
     Tcl script.  The result is returned
     from the Tcl code in the usual way, with a <literal>return</literal>
     statement.
    </para>

    <para>
     For example, a function
     returning the greater of two integer values could be defined as:

<programlisting>
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {$1 &gt; $2} {return $1}
    return $2
$$ LANGUAGE pltcl STRICT;
</programlisting>

     Note the clause <literal>STRICT</>, which saves us from
     having to think about null input values: if a null value is passed, the
     function will not be called at all, but will just return a null
     result automatically.
    </para>

    <para>
     In a nonstrict function,
     if the actual value of an argument is null, the corresponding
     <literal>$<replaceable>n</replaceable></literal> variable will be set to an empty string.
     To detect whether a particular argument is null, use the function
     <literal>argisnull</>.  For example, suppose that we wanted <function>tcl_max</function>
     with one null and one nonnull argument to return the nonnull
     argument, rather than null:

<programlisting>
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
    if {[argisnull 1]} {
        if {[argisnull 2]} { return_null }
        return $2
    }
    if {[argisnull 2]} { return $1 }
    if {$1 &gt; $2} {return $1}
    return $2
$$ LANGUAGE pltcl;
</programlisting>
    </para>

    <para>
     As shown above,
     to return a null value from a PL/Tcl function, execute
     <literal>return_null</literal>.  This can be done whether the
     function is strict or not.
    </para>

    <para>
     Composite-type arguments are passed to the function as Tcl
     arrays.  The element names of the array are the attribute names
     of the composite type. If an attribute in the passed row has the
     null value, it will not appear in the array. Here is an example:

<programlisting>
CREATE TABLE employee (
    name text,
    salary integer,
    age integer
);

CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
    if {200000.0 &lt; $1(salary)} {
        return "t"
    }
    if {$1(age) &lt; 30 &amp;&amp; 100000.0 &lt; $1(salary)} {
        return "t"
    }
    return "f"
$$ LANGUAGE pltcl;
</programlisting>
    </para>

    <para>
     There is currently no support for returning a composite-type
     result value, nor for returning sets.
    </para>

    <para>
     <application>PL/Tcl</> does not currently have full support for
     domain types: it treats a domain the same as the underlying scalar
     type.  This means that constraints associated with the domain will
     not be enforced.  This is not an issue for function arguments, but
     it is a hazard if you declare a <application>PL/Tcl</> function
     as returning a domain type.
    </para>

   </sect1>

   <sect1 id="pltcl-data">
    <title>Data Values in PL/Tcl</title>

    <para>
     The argument values supplied to a PL/Tcl function's code are simply
     the input arguments converted to text form (just as if they had been
     displayed by a <command>SELECT</> statement).  Conversely, the
     <literal>return</>
     command will accept any string that is acceptable input format for
     the function's declared return type.  So, within the PL/Tcl function,
     all values are just text strings.
    </para>

   </sect1>

   <sect1 id="pltcl-global">
    <title>Global Data in PL/Tcl</title>

    <indexterm zone="pltcl-global">
     <primary>global data</primary>
     <secondary>in PL/Tcl</secondary>
    </indexterm>

    <para>
     Sometimes it
     is useful to have some global data that is held between two
     calls to a function or is shared between different functions.
     This is easily done since
     all PL/Tcl functions executed in one session share the same
     safe Tcl interpreter.  So, any global Tcl variable is accessible to
     all PL/Tcl function calls and will persist for the duration of the
     SQL session.  (Note that <application>PL/TclU</> functions likewise share
     global data, but they are in a different Tcl interpreter and cannot
     communicate with PL/Tcl functions.)
    </para>
    <para>
     To help protect PL/Tcl functions from unintentionally interfering
     with each other, a global
     array is made available to each function via the <function>upvar</>
     command. The global name of this variable is the function's internal
     name, and the local name is <literal>GD</>.  It is recommended that
     <literal>GD</> be used
     for persistent private data of a function.  Use regular Tcl global
     variables only for values that you specifically intend to be shared among
     multiple functions.
    </para>

    <para>
     An example of using <literal>GD</> appears in the
     <function>spi_execp</function> example below.
    </para>
   </sect1>

   <sect1 id="pltcl-dbaccess">
    <title>Database Access from PL/Tcl</title>

    <para>
     The following commands are available to access the database from
     the body of a PL/Tcl function:

    <variablelist>

     <varlistentry>
      <term><literal><function>spi_exec</function> <optional role="tcl">-count <replaceable>n</replaceable></optional> <optional role="tcl">-array <replaceable>name</replaceable></optional> <replaceable>command</replaceable> <optional role="tcl"><replaceable>loop-body</replaceable></optional></literal></term>
      <listitem>
       <para>
        Executes an SQL command given as a string.  An error in the command
        causes an error to be raised.  Otherwise, the return value of <function>spi_exec</function>
        is the number of rows processed (selected, inserted, updated, or
        deleted) by the command, or zero if the command is a utility
        statement.  In addition, if the command is a <command>SELECT</> statement, the
        values of the selected columns are placed in Tcl variables as
        described below.
       </para>
       <para>
        The optional <literal>-count</> value tells
        <function>spi_exec</function> the maximum number of rows
        to process in the command.  The effect of this is comparable to
        setting up a query as a cursor and then saying <literal>FETCH <replaceable>n</></>.
       </para>
       <para>
        If the command is a <command>SELECT</> statement, the values of the
        result columns are placed into Tcl variables named after the columns.
        If the <literal>-array</> option is given, the column values are
        instead stored into the named associative array, with the
        column names used as array indexes.
       </para>
       <para>
        If the command is a <command>SELECT</> statement and no <replaceable>loop-body</>
        script is given, then only the first row of results are stored into
        Tcl variables; remaining rows, if any, are ignored.  No storing occurs
        if the 
        query returns no rows.  (This case can be detected by checking the
        result of <function>spi_exec</function>.)  For example:
<programlisting>
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
</programlisting>

        will set the Tcl variable <literal>$cnt</> to the number of rows in
        the <structname>pg_proc</> system catalog.
       </para>
       <para>
        If the optional <replaceable>loop-body</> argument is given, it is
        a piece of Tcl script that is executed once for each row in the
        query result.  (<replaceable>loop-body</> is ignored if the given
        command is not a <command>SELECT</>.)  The values of the current row's columns
        are stored into Tcl variables before each iteration.  For example:

<programlisting>
spi_exec -array C "SELECT * FROM pg_class" {
    elog DEBUG "have table $C(relname)"
}
</programlisting>

        will print a log message for every row of <literal>pg_class</>.  This
        feature works similarly to other Tcl looping constructs; in
        particular <literal>continue</> and <literal>break</> work in the
        usual way inside the loop body.
       </para>
       <para>
        If a column of a query result is null, the target
        variable for it is <quote>unset</> rather than being set.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><function>spi_prepare</function> <replaceable>query</replaceable> <replaceable>typelist</replaceable></term>
      <listitem>
       <para>
        Prepares and saves a query plan for later execution.  The
        saved plan will be retained for the life of the current
        session.<indexterm><primary>preparing a query</><secondary>in
        PL/Tcl</></>
       </para>
       <para>
        The query can use parameters, that is, placeholders for
        values to be supplied whenever the plan is actually executed.
        In the query string, refer to parameters
        by the symbols <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal>.
        If the query uses parameters, the names of the parameter types
        must be given as a Tcl list.  (Write an empty list for
        <replaceable>typelist</replaceable> if no parameters are used.)
       </para>
       <para>
        The return value from <function>spi_prepare</function> is a query ID
        to be used in subsequent calls to <function>spi_execp</function>. See
        <function>spi_execp</function> for an example.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><literal><function>spi_execp</> <optional role="tcl">-count <replaceable>n</replaceable></optional> <optional role="tcl">-array <replaceable>name</replaceable></optional> <optional role="tcl">-nulls <replaceable>string</replaceable></optional> <replaceable>queryid</replaceable> <optional role="tcl"><replaceable>value-list</replaceable></optional> <optional role="tcl"><replaceable>loop-body</replaceable></optional></literal></term>
      <listitem>
       <para>
        Executes a query previously prepared with <function>spi_prepare</>.
        <replaceable>queryid</replaceable> is the ID returned by
        <function>spi_prepare</>.  If the query references parameters,
        a <replaceable>value-list</replaceable> must be supplied.  This
        is a Tcl list of actual values for the parameters.  The list must be
        the same length as the parameter type list previously given to
        <function>spi_prepare</>.  Omit <replaceable>value-list</replaceable>
        if the query has no parameters.
       </para>
       <para>
        The optional value for <literal>-nulls</> is a string of spaces and
        <literal>'n'</> characters telling <function>spi_execp</function>
        which of the parameters are null values. If given, it must have exactly the
        same length as the <replaceable>value-list</replaceable>.  If it
        is not given, all the parameter values are nonnull.
       </para>
       <para>
        Except for the way in which the query and its parameters are specified,
        <function>spi_execp</> works just like <function>spi_exec</>.
        The <literal>-count</>, <literal>-array</>, and
        <replaceable>loop-body</replaceable> options are the same,
        and so is the result value.
       </para>
       <para>
        Here's an example of a PL/Tcl function using a prepared plan:

<programlisting>
CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
    if {![ info exists GD(plan) ]} {
        # prepare the saved plan on the first call
        set GD(plan) [ spi_prepare \
                "SELECT count(*) AS cnt FROM t1 WHERE num &gt;= \$1 AND num &lt;= \$2" \
                [ list int4 int4 ] ]
    }
    spi_execp -count 1 $GD(plan) [ list $1 $2 ]
    return $cnt
$$ LANGUAGE pltcl;
</programlisting>

        We need backslashes inside the query string given to
        <function>spi_prepare</> to ensure that the
        <literal>$<replaceable>n</replaceable></> markers will be passed
        through to <function>spi_prepare</> as-is, and not replaced by Tcl
        variable substitution.

       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <indexterm>
       <primary>spi_lastoid</primary>
      </indexterm>
      <term><function>spi_lastoid</></term>
      <listitem>
       <para>
        Returns the OID of the row inserted by the last
        <function>spi_exec</> or <function>spi_execp</>, if the
        command was a single-row <command>INSERT</> and the modified
        table contained OIDs.  (If not, you get zero.)
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><function>quote</> <replaceable>string</replaceable></term>
      <listitem>
       <para>
        Doubles all occurrences of single quote and backslash characters
        in the given string.  This can be used to safely quote strings
        that are to be inserted into SQL commands given
        to <function>spi_exec</function> or
        <function>spi_prepare</function>.
        For example, think about an SQL command string like:

<programlisting>
"SELECT '$val' AS ret"
</programlisting>

        where the Tcl variable <literal>val</> actually contains
        <literal>doesn't</literal>. This would result
        in the final command string:

<programlisting>
SELECT 'doesn't' AS ret
</programlisting>

        which would cause a parse error during
        <function>spi_exec</function> or
        <function>spi_prepare</function>.
        To work properly, the submitted command should contain:

<programlisting>
SELECT 'doesn''t' AS ret
</programlisting>

        which can be formed in PL/Tcl using:

<programlisting>
"SELECT '[ quote $val ]' AS ret"
</programlisting>

        One advantage of <function>spi_execp</function> is that you don't
        have to quote parameter values like this, since the parameters are never
        parsed as part of an SQL command string.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <indexterm>
       <primary>elog</primary>
       <secondary>in PL/Tcl</secondary>
      </indexterm>
      <term><function>elog</> <replaceable>level</replaceable> <replaceable>msg</replaceable></term>
      <listitem>
       <para>
        Emits a log or error message. Possible levels are
        <literal>DEBUG</>, <literal>LOG</>, <literal>INFO</>,
        <literal>NOTICE</>, <literal>WARNING</>, <literal>ERROR</>, and
        <literal>FATAL</>. <literal>ERROR</>
        raises an error condition; if this is not trapped by the surrounding
        Tcl code, the error propagates out to the calling query, causing
        the current transaction or subtransaction to be aborted.  This
        is effectively the same as the Tcl <literal>error</> command.
        <literal>FATAL</> aborts the transaction and causes the current
        session to shut down.  (There is probably no good reason to use
        this error level in PL/Tcl functions, but it's provided for
        completeness.)  The other levels only generate messages of different
        priority levels.
        Whether messages of a particular priority are reported to the client,
        written to the server log, or both is controlled by the
        <xref linkend="guc-log-min-messages"> and
        <xref linkend="guc-client-min-messages"> configuration
        variables. See <xref linkend="runtime-config"> for more
        information.
       </para>
      </listitem>
     </varlistentry>

    </variablelist>
    </para>

   </sect1>

   <sect1 id="pltcl-trigger">
    <title>Trigger Procedures in PL/Tcl</title>

    <indexterm>
     <primary>trigger</primary>
     <secondary>in PL/Tcl</secondary>
    </indexterm>

    <para>
     Trigger procedures can be written in PL/Tcl.
     <productname>PostgreSQL</productname> requires that a procedure that is to be called
     as a trigger must be declared as a function with no arguments
     and a return type of <literal>trigger</>.
    </para>
    <para>
     The information from the trigger manager is passed to the procedure body
     in the following variables:

     <variablelist>

      <varlistentry>
       <term><varname>$TG_name</varname></term>
       <listitem>
        <para>
         The name of the trigger from the <command>CREATE TRIGGER</command> statement.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_relid</varname></term>
       <listitem>
        <para>
         The object ID of the table that caused the trigger procedure
         to be invoked.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_table_name</varname></term>
       <listitem>
        <para>
         The name of the table that caused the trigger procedure
         to be invoked.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_table_schema</varname></term>
       <listitem>
        <para>
         The schema of the table that caused the trigger procedure
         to be invoked.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_relatts</varname></term>
       <listitem>
        <para>
         A Tcl list of the table column names, prefixed with an empty list
         element. So looking up a column name in the list with <application>Tcl</>'s
         <function>lsearch</> command returns the element's number starting
         with 1 for the first column, the same way the columns are customarily
         numbered in <productname>PostgreSQL</productname>.  (Empty list
         elements also appear in the positions of columns that have been
         dropped, so that the attribute numbering is correct for columns
         to their right.)
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_when</varname></term>
       <listitem>
        <para>
         The string <literal>BEFORE</> or <literal>AFTER</> depending on the
         type of trigger event.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_level</varname></term>
       <listitem>
        <para>
         The string <literal>ROW</> or <literal>STATEMENT</> depending on the
         type of trigger event.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$TG_op</varname></term>
       <listitem>
        <para>
         The string <literal>INSERT</>, <literal>UPDATE</>,
         <literal>DELETE</>, or <literal>TRUNCATE</> depending on the type of
         trigger event.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$NEW</varname></term>
       <listitem>
        <para>
         An associative array containing the values of the new table
         row for <command>INSERT</> or <command>UPDATE</> actions, or
         empty for <command>DELETE</>.  The array is indexed by column
         name.  Columns that are null will not appear in the array.
         This is not set for statement-level triggers.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$OLD</varname></term>
       <listitem>
        <para>
         An associative array containing the values of the old table
         row for <command>UPDATE</> or <command>DELETE</> actions, or
         empty for <command>INSERT</>.  The array is indexed by column
         name.  Columns that are null will not appear in the array.
         This is not set for statement-level triggers.
        </para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><varname>$args</varname></term>
       <listitem>
        <para>
         A Tcl list of the arguments to the procedure as given in the
         <command>CREATE TRIGGER</command> statement. These arguments are also accessible as
         <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal> in the procedure body.
        </para>
       </listitem>
      </varlistentry>

     </variablelist>
    </para>

    <para>
     The return value from a trigger procedure can be one of the strings
     <literal>OK</> or <literal>SKIP</>, or a list as returned by the
     <literal>array get</> Tcl command. If the return value is <literal>OK</>,
     the operation (<command>INSERT</>/<command>UPDATE</>/<command>DELETE</>) that fired the trigger will proceed
     normally. <literal>SKIP</> tells the trigger manager to silently suppress
     the operation for this row. If a list is returned, it tells PL/Tcl to
     return a modified row to the trigger manager that will be inserted
     instead of the one given in <varname>$NEW</>.  (This works for <command>INSERT</> and <command>UPDATE</>
     only.) Needless to say that all this is only meaningful when the trigger
     is <literal>BEFORE</> and <command>FOR EACH ROW</>; otherwise the return value is ignored.
    </para>

    <para>
     Here's a little example trigger procedure that forces an integer value
     in a table to keep track of the number of updates that are performed on the
     row. For new rows inserted, the value is initialized to 0 and then
     incremented on every update operation.

<programlisting>
CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
    switch $TG_op {
        INSERT {
            set NEW($1) 0
        }
        UPDATE {
            set NEW($1) $OLD($1)
            incr NEW($1)
        }
        default {
            return OK
        }
    }
    return [array get NEW]
$$ LANGUAGE pltcl;

CREATE TABLE mytab (num integer, description text, modcnt integer);

CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
    FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt');
</programlisting>

     Notice that the trigger procedure itself does not know the column
     name; that's supplied from the trigger arguments.  This lets the
     trigger procedure be reused with different tables.
    </para>
   </sect1>

   <sect1 id="pltcl-unknown">
       <title>Modules and the <function>unknown</> command</title>
       <para>
        PL/Tcl has support for autoloading Tcl code when used.
        It recognizes a special table, <literal>pltcl_modules</>, which
        is presumed to contain modules of Tcl code.  If this table
        exists, the module <literal>unknown</> is fetched from the table
        and loaded into the Tcl interpreter immediately before the first
        execution of a PL/Tcl function in a database session.  (This
        happens separately for PL/Tcl and PL/TclU, if both are used,
        because separate interpreters are used for the two languages.)
       </para>
       <para>
        While the <literal>unknown</> module could actually contain any
        initialization script you need, it normally defines a Tcl
        <function>unknown</> procedure that is invoked whenever Tcl does
        not recognize an invoked procedure name.  <application>PL/Tcl</>'s standard version
        of this procedure tries to find a module in <literal>pltcl_modules</>
        that will define the required procedure.  If one is found, it is
        loaded into the interpreter, and then execution is allowed to
        proceed with the originally attempted procedure call.  A
        secondary table <literal>pltcl_modfuncs</> provides an index of
        which functions are defined by which modules, so that the lookup
        is reasonably quick.
       </para>
       <para>
        The <productname>PostgreSQL</productname> distribution includes
        support scripts to maintain these tables:
        <command>pltcl_loadmod</>, <command>pltcl_listmod</>,
        <command>pltcl_delmod</>, as well as source for the standard
        <literal>unknown</> module in <filename>share/unknown.pltcl</>.  This module
        must be loaded
        into each database initially to support the autoloading mechanism.
       </para>
       <para>
        The tables <literal>pltcl_modules</> and <literal>pltcl_modfuncs</>
        must be readable by all, but it is wise to make them owned and
        writable only by the database administrator.  As a security
        precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
        not attempt to load the <literal>unknown</> module) unless it is
        owned by a superuser.  But update privileges on this table can be
        granted to other users, if you trust them sufficiently.
       </para>
   </sect1>

   <sect1 id="pltcl-procnames">
    <title>Tcl Procedure Names</title>

    <para>
     In <productname>PostgreSQL</productname>, the same function name can be used for
     different function definitions as long as the number of arguments or their types
     differ. Tcl, however, requires all procedure names to be distinct.
     PL/Tcl deals with this by making the internal Tcl procedure names contain
     the object 
     ID of the function from the system table <structname>pg_proc</> as part of their name. Thus,
     <productname>PostgreSQL</productname> functions with the same name
     and different argument types will be different Tcl procedures, too.  This
     is not normally a concern for a PL/Tcl programmer, but it might be visible
     when debugging.
    </para>

   </sect1>
 </chapter>
@


2.49
log
@Remove unnecessary xref endterm attributes and title ids

The endterm attribute is mainly useful when the toolchain does not support
automatic link target text generation for a particular situation.  In  the
past, this was required by the man page tools for all reference page links,
but that is no longer the case, and it now actually gets in the way of
proper automatic link text generation.  The only remaining use cases are
currently xrefs to refsects.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.48 2008/03/28 00:21:55 tgl Exp $ -->
d692 4
a695 2
        and loaded into the Tcl interpreter immediately after creating
        the interpreter.
d722 5
a726 1
        writable only by the database administrator.
@


2.48
log
@Support statement-level ON TRUNCATE triggers.  Simon Riggs
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.47 2007/12/03 23:49:50 tgl Exp $ -->
d82 1
a82 2
     the standard <xref linkend="sql-createfunction"
     endterm="sql-createfunction-title"> syntax:
@


2.48.2.1
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.48 2008/03/28 00:21:55 tgl Exp $ -->
d693 2
a694 4
        and loaded into the Tcl interpreter immediately before the first
        execution of a PL/Tcl function in a database session.  (This
        happens separately for PL/Tcl and PL/TclU, if both are used,
        because separate interpreters are used for the two languages.)
d721 1
a721 5
        writable only by the database administrator.  As a security
        precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
        not attempt to load the <literal>unknown</> module) unless it is
        owned by a superuser.  But update privileges on this table can be
        granted to other users, if you trust them sufficiently.
@


2.47
log
@Entity-ify a passel of & < > characters.  Per gripe from Devrim.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.46 2007/02/21 03:27:31 adunstan Exp $ -->
d572 1
a572 1
         type of trigger call.
d582 1
a582 1
         type of trigger call.
d591 3
a593 2
         The string <literal>INSERT</>, <literal>UPDATE</>, or
         <literal>DELETE</> depending on the type of trigger call.
d606 1
d619 1
d650 1
@


2.47.2.1
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.47 2007/12/03 23:49:50 tgl Exp $ -->
d689 2
a690 4
        and loaded into the Tcl interpreter immediately before the first
        execution of a PL/Tcl function in a database session.  (This
        happens separately for PL/Tcl and PL/TclU, if both are used,
        because separate interpreters are used for the two languages.)
d717 1
a717 5
        writable only by the database administrator.  As a security
        precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
        not attempt to load the <literal>unknown</> module) unless it is
        owned by a superuser.  But update privileges on this table can be
        granted to other users, if you trust them sufficiently.
@


2.46
log
@Allow pltcl args to spi_prepare and plpython args to plpy.prepare to be standard type aliases as well as those known in pg_type. Similar to recent change in plperl.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.45 2007/02/01 00:28:17 momjian Exp $ -->
d167 1
a167 1
    if {$1(age) &lt; 30 && 100000.0 &lt; $1(salary)} {
@


2.45
log
@Consistenly use colons before '<programlisting>' blocks, where
appropriate.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.44 2007/01/31 20:56:18 momjian Exp $ -->
a333 3
        Presently, the parameter types must be identified by the internal
        type names shown in the system table <literal>pg_type</>; for example <literal>int4</> not
        <literal>integer</>.
@


2.44
log
@Update documentation on may/can/might:

Standard English uses "may", "can", and "might" in different ways:

        may - permission, "You may borrow my rake."

        can - ability, "I can lift that log."

        might - possibility, "It might rain today."

Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice.  Similarly, "It may crash" is better stated, "It might crash".

Also update two error messages mentioned in the documenation to match.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.43 2007/01/30 22:29:23 momjian Exp $ -->
d284 1
a284 2
        result of <function>spi_exec</function>.)  For example,

d297 1
a297 1
        are stored into Tcl variables before each iteration.  For example,
d423 1
a423 1
        For example, think about an SQL command string like
d431 1
a431 1
        in the final command string
d440 1
a440 1
        To work properly, the submitted command should contain
d446 1
a446 1
        which can be formed in PL/Tcl using
@


2.43
log
@Update documentation for backslashes to mention escape string syntax
more, and standard_conforming_strings less, because in the future non-E
strings will not treat backslashes specially.

Also use E'' strings where backslashes are used in examples. (The
existing examples would have drawn warnings.)

Backpatch to 8.2.X.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.42 2006/09/16 00:30:15 momjian Exp $ -->
d42 1
a42 1
    function can do.  Thus, unprivileged database users may be trusted
d47 1
a47 1
    may not be used to create input/output functions for new data
d328 1
a328 1
        The query may use parameters, that is, placeholders for
d420 1
a420 1
        in the given string.  This may be used to safely quote strings
d729 2
a730 3
     In <productname>PostgreSQL</productname>, one and the 
     same function name can be used for
     different functions as long as the number of arguments or their types
@


2.42
log
@Remove emacs info from footer of SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.41 2006/05/30 11:40:21 momjian Exp $ -->
d390 5
a394 5
    We need backslashes inside the query string given to
    <function>spi_prepare</> to ensure that the
    <literal>$<replaceable>n</replaceable></> markers will be passed
    through to <function>spi_prepare</> as-is, and not replaced by Tcl
    variable substitution.
@


2.42.2.1
log
@Update documentation for backslashes to mention escape string syntax
more, and standard_conforming_strings less, because in the future non-E
strings will not treat backslashes specially.

Also use E'' strings where backslashes are used in examples. (The
existing examples would have drawn warnings.)

Backpatch to 8.2.X.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.42 2006/09/16 00:30:15 momjian Exp $ -->
d390 5
a394 5
        We need backslashes inside the query string given to
        <function>spi_prepare</> to ensure that the
        <literal>$<replaceable>n</replaceable></> markers will be passed
        through to <function>spi_prepare</> as-is, and not replaced by Tcl
        variable substitution.
@


2.42.2.2
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.42.2.1 2007/01/30 22:29:40 momjian Exp $ -->
d693 2
a694 4
        and loaded into the Tcl interpreter immediately before the first
        execution of a PL/Tcl function in a database session.  (This
        happens separately for PL/Tcl and PL/TclU, if both are used,
        because separate interpreters are used for the two languages.)
d721 1
a721 5
        writable only by the database administrator.  As a security
        precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
        not attempt to load the <literal>unknown</> module) unless it is
        owned by a superuser.  But update privileges on this table can be
        granted to other users, if you trust them sufficiently.
@


2.41
log
@Update PL documentation:

An article at WebProNews quoted from the PG docs as to the merits of
stored procedures.  I have added a bit more material on their merits,
as well as making a few changes to improve the introductions to
PL/Perl and PL/Tcl.

Chris Browne
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.40 2006/05/27 20:24:16 adunstan Exp $ -->
a743 17

<!-- 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:
-->
@


2.40
log
@
TG_table_name and TG_table_schema for pl/tcl, plus regression test and docs.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.39 2006/03/10 19:10:48 momjian Exp $ -->
d28 4
a31 2
    PL/Tcl offers most of the capabilities a function
    writer has in the C language, except for some restrictions.
d34 10
a43 8
    The good restriction is that everything is executed in a safe
    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()</>. There is 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, any unprivileged database user may be
    permitted to use this language.
d46 3
a48 2
    The other, implementation restriction is that Tcl functions cannot
    be used to create input/output functions for new data types.
d63 6
a68 6
    The shared object for the <application>PL/Tcl</> and <application>PL/TclU</> 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</> and/or <application>PL/TclU</> in a particular database, use the
@


2.39
log
@Make $PostgreSQL CVS tags consistent for SGML files.
@
text
@d1 1
a1 1
<!-- $PostgreSQL: pgsql/doc/src/sgml/advanced.sgml,v 1.49 2005/04/09 03:52:43 momjian Exp $ -->
d531 20
@


2.38
log
@Add some links to the CREATE FUNCTION reference page when describing
function definition for particular PLs. Original patch from David
Fetter, editorializing by Neil Conway.
@
text
@d1 1
a1 3
<!--
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.37 2005/04/09 03:52:43 momjian Exp $
-->
@


2.38.2.1
log
@Backpatch documentation additions for PL language choice and
regex_replace() to 8.1.X.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.38 2005/05/20 01:52:25 neilc Exp $
d30 2
a31 4
    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.
d34 8
a41 10
    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()</>.  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 may be trusted
    to use this language; it does not give them unlimited authority.
d44 2
a45 3
    The other notable implementation restriction is that Tcl functions
    may not be used to create input/output functions for new data
    types.
d60 6
a65 6
    The shared object code for the <application>PL/Tcl</> and
    <application>PL/TclU</> 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</>
    and/or <application>PL/TclU</> in a particular database, use the
@


2.38.2.2
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.38.2.1 2006/05/30 12:32:37 momjian Exp $
d675 2
a676 4
        and loaded into the Tcl interpreter immediately before the first
        execution of a PL/Tcl function in a database session.  (This
        happens separately for PL/Tcl and PL/TclU, if both are used,
        because separate interpreters are used for the two languages.)
d703 1
a703 5
        writable only by the database administrator.  As a security
        precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
        not attempt to load the <literal>unknown</> module) unless it is
        owned by a superuser.  But update privileges on this table can be
        granted to other users, if you trust them sufficiently.
@


2.37
log
@We don't put URL's in ulink's because the URL is always generated, but
we can put words in ulink and the URL will still be printed.

per Peter
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.36 2005/03/31 03:54:38 momjian Exp $
d78 3
a80 1
     To create a function in the <application>PL/Tcl</> language, use the standard syntax:
@


2.36
log
@Adjust SGML ulink tags to the URL is always displayed in our printed docs.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.35 2005/03/13 09:36:30 neilc Exp $
d19 2
a20 2
   that enables the Tcl language, <ulink url="http://www.tcl.tk/"></ulink>,
   to be used to write functions and
@


2.35
log
@Make default_with_oids default to false -- user-created tables will now
no longer include OIDs, unless WITH OIDS is specified or the
default_with_oids configuration parameter is enabled. Update the docs
accordingly.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.34 2005/01/22 22:56:36 momjian Exp $
d19 2
a20 2
   that enables the <ulink url="http://www.tcl.tk/">Tcl</ulink>
   language to be used to write functions and
@


2.34
log
@More < and > cleanups converted to ampersands.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.33 2004/12/30 21:45:37 tgl Exp $
d403 3
a405 2
        <function>spi_exec</> or <function>spi_execp</>,
        if the command was a single-row <command>INSERT</>.  (If not, you get zero.)
@


2.33
log
@More minor updates and copy-editing.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.32 2004/11/21 21:17:02 tgl Exp $
d105 1
a105 1
    if {$1 > $2} {return $1}
d132 1
a132 1
    if {$1 > $2} {return $1}
d159 1
a159 1
    if {200000.0 < $1(salary)} {
d162 1
a162 1
    if {$1(age) < 30 && 100000.0 < $1(salary)} {
@


2.33.4.1
log
@More < and > cleanups converted to ampersands.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.33 2004/12/30 21:45:37 tgl Exp $
d105 1
a105 1
    if {$1 &gt; $2} {return $1}
d132 1
a132 1
    if {$1 &gt; $2} {return $1}
d159 1
a159 1
    if {200000.0 &lt; $1(salary)} {
d162 1
a162 1
    if {$1(age) &lt; 30 && 100000.0 &lt; $1(salary)} {
@


2.33.4.2
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.33.4.1 2005/01/22 23:05:48 momjian Exp $
d667 2
a668 4
        and loaded into the Tcl interpreter immediately before the first
        execution of a PL/Tcl function in a database session.  (This
        happens separately for PL/Tcl and PL/TclU, if both are used,
        because separate interpreters are used for the two languages.)
d695 1
a695 5
        writable only by the database administrator.  As a security
        precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
        not attempt to load the <literal>unknown</> module) unless it is
        owned by a superuser.  But update privileges on this table can be
        granted to other users, if you trust them sufficiently.
@


2.32
log
@Fix plperl and pltcl error handling per my previous proposal.  SPI
operations are now run as subtransactions, so that errors in them
can be reported as ordinary Perl or Tcl errors and caught by the
normal error handling convention of those languages.  Also do some
minor code cleanup in pltcl.c: extract a large chunk of duplicated
code in pltcl_SPI_execute and pltcl_SPI_execute_plan into a shared
subroutine.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.31 2004/09/20 22:48:25 tgl Exp $
d19 2
a20 1
   that enables the Tcl language to be used to write functions and
d63 1
a63 1
    library directory if Tcl/Tk support is specified
d81 1
a81 2
CREATE FUNCTION <replaceable>funcname</replaceable>
(<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS $$
d172 10
a181 1
     result value.
d192 2
a193 1
     displayed by a <command>SELECT</> statement).  Conversely, the <literal>return</>
d195 2
a196 2
     the function's declared return type.  So, the PL/Tcl programmer can
     manipulate data values as if they were just text.
d228 3
a230 3
     for private data of a function.  Use regular Tcl global variables
     only for values that you specifically intend to be shared among multiple
     functions.
d252 13
a264 13
	Executes an SQL command given as a string.  An error in the command
	causes an error to be raised.  Otherwise, the return value of <function>spi_exec</function>
	is the number of rows processed (selected, inserted, updated, or
	deleted) by the command, or zero if the command is a utility
	statement.  In addition, if the command is a <command>SELECT</> statement, the
	values of the selected columns are placed in Tcl variables as
	described below.
       </para>
       <para>
	The optional <literal>-count</> value tells
	<function>spi_exec</function> the maximum number of rows
	to process in the command.  The effect of this is comparable to
	setting up a query as a cursor and then saying <literal>FETCH <replaceable>n</></>.
d267 2
a268 2
	If the command is a <command>SELECT</> statement, the values of the
	result columns are placed into Tcl variables named after the columns.
d270 2
a271 2
	instead stored into the named associative array, with the
	column names used as array indexes.
d275 5
a279 5
	script is given, then only the first row of results are stored into
	Tcl variables; remaining rows, if any, are ignored.  No storing occurs
	if the 
	query returns no rows.  (This case can be detected by checking the
	result of <function>spi_exec</function>.)  For example,
d285 2
a286 2
	will set the Tcl variable <literal>$cnt</> to the number of rows in
	the <structname>pg_proc</> system catalog.
d290 4
a293 4
	a piece of Tcl script that is executed once for each row in the
	query result.  (<replaceable>loop-body</> is ignored if the given
	command is not a <command>SELECT</>.)  The values of the current row's columns
	are stored into Tcl variables before each iteration.  For example,
d301 4
a304 4
	will print a log message for every row of <literal>pg_class</>.  This
	feature works similarly to other Tcl looping constructs; in
	particular <literal>continue</> and <literal>break</> work in the
	usual way inside the loop body.
d308 1
a308 1
	variable for it is <quote>unset</> rather than being set.
d317 4
a320 4
	Prepares and saves a query plan for later execution.  The
	saved plan will be retained for the life of the current
	session.<indexterm><primary>preparing a query</><secondary>in
	PL/Tcl</></>
d324 9
a332 9
	values to be supplied whenever the plan is actually executed.
	In the query string, refer to parameters
	by the symbols <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal>.
	If the query uses parameters, the names of the parameter types
	must be given as a Tcl list.  (Write an empty list for
	<replaceable>typelist</replaceable> if no parameters are used.)
	Presently, the parameter types must be identified by the internal
	type names shown in the system table <literal>pg_type</>; for example <literal>int4</> not
	<literal>integer</>.
d336 2
a337 2
	to be used in subsequent calls to <function>spi_execp</function>. See
	<function>spi_execp</function> for an example.
d346 8
a353 8
	Executes a query previously prepared with <function>spi_prepare</>.
	<replaceable>queryid</replaceable> is the ID returned by
	<function>spi_prepare</>.  If the query references parameters,
	a <replaceable>value-list</replaceable> must be supplied.  This
	is a Tcl list of actual values for the parameters.  The list must be
	the same length as the parameter type list previously given to
	<function>spi_prepare</>.  Omit <replaceable>value-list</replaceable>
	if the query has no parameters.
d356 5
a360 5
	The optional value for <literal>-nulls</> is a string of spaces and
	<literal>'n'</> characters telling <function>spi_execp</function>
	which of the parameters are null values. If given, it must have exactly the
	same length as the <replaceable>value-list</replaceable>.  If it
	is not given, all the parameter values are nonnull.
d364 1
a364 1
	<function>spi_execp</> works just like <function>spi_exec</>.
d366 2
a367 2
	<replaceable>loop-body</replaceable> options are the same,
	and so is the result value.
d370 1
a370 1
	Here's an example of a PL/Tcl function using a prepared plan:
d402 3
a404 3
	Returns the OID of the row inserted by the last
	<function>spi_exec</> or <function>spi_execp</>,
	if the command was a single-row <command>INSERT</>.  (If not, you get zero.)
d413 6
a418 6
	Doubles all occurrences of single quote and backslash characters
	in the given string.  This may be used to safely quote strings
	that are to be inserted into SQL commands given
	to <function>spi_exec</function> or
	<function>spi_prepare</function>.
	For example, think about an SQL command string like
d424 3
a426 3
	where the Tcl variable <literal>val</> actually contains
	<literal>doesn't</literal>. This would result
	in the final command string
d432 4
a435 4
	which would cause a parse error during
	<function>spi_exec</function> or
	<function>spi_prepare</function>.
	To work properly, the submitted command should contain
d441 1
a441 1
	which can be formed in PL/Tcl using
d448 2
a449 2
	have to quote parameter values like this, since the parameters are never
	parsed as part of an SQL command string.
d465 1
a465 2
        <literal>FATAL</>. Most simply emit the given message just like
        the <literal>elog</> C function. <literal>ERROR</>
d473 8
a480 1
        completeness.)
d513 3
a515 3
	<para>
	 The name of the trigger from the <command>CREATE TRIGGER</command> statement.
	</para>
d522 4
a525 4
	<para>
	 The object ID of the table that caused the trigger procedure
	 to be invoked.
	</para>
d532 2
a533 2
	<para>
	 A Tcl list of the table column names, prefixed with an empty list
d536 6
a541 6
	 with 1 for the first column, the same way the columns are customarily
	 numbered in <productname>PostgreSQL</productname>.  (Empty list
	 elements also appear in the positions of columns that have been
	 dropped, so that the attribute numbering is correct for columns
	 to their right.)
	</para>
d548 4
a551 4
	<para>
	 The string <literal>BEFORE</> or <literal>AFTER</> depending on the
	 type of trigger call.
	</para>
d558 4
a561 4
	<para>
	 The string <literal>ROW</> or <literal>STATEMENT</> depending on the
	 type of trigger call.
	</para>
d568 4
a571 4
	<para>
	 The string <literal>INSERT</>, <literal>UPDATE</>, or
	 <literal>DELETE</> depending on the type of trigger call.
	</para>
d578 6
a583 6
	<para>
	 An associative array containing the values of the new table
	 row for <command>INSERT</> or <command>UPDATE</> actions, or
	 empty for <command>DELETE</>.  The array is indexed by column
	 name.  Columns that are null will not appear in the array.
	</para>
d590 6
a595 6
	<para>
	 An associative array containing the values of the old table
	 row for <command>UPDATE</> or <command>DELETE</> actions, or
	 empty for <command>INSERT</>.  The array is indexed by column
	 name.  Columns that are null will not appear in the array.
	</para>
d602 5
a606 5
	<para>
	 A Tcl list of the arguments to the procedure as given in the
	 <command>CREATE TRIGGER</command> statement. These arguments are also accessible as
	 <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal> in the procedure body.
	</para>
d663 6
a668 6
	PL/Tcl has support for autoloading Tcl code when used.
	It recognizes a special table, <literal>pltcl_modules</>, which
	is presumed to contain modules of Tcl code.  If this table
	exists, the module <literal>unknown</> is fetched from the table
	and loaded into the Tcl interpreter immediately after creating
	the interpreter.
d672 10
a681 10
	initialization script you need, it normally defines a Tcl
	<function>unknown</> procedure that is invoked whenever Tcl does
	not recognize an invoked procedure name.  <application>PL/Tcl</>'s standard version
	of this procedure tries to find a module in <literal>pltcl_modules</>
	that will define the required procedure.  If one is found, it is
	loaded into the interpreter, and then execution is allowed to
	proceed with the originally attempted procedure call.  A
	secondary table <literal>pltcl_modfuncs</> provides an index of
	which functions are defined by which modules, so that the lookup
	is reasonably quick.
d685 6
a690 6
	support scripts to maintain these tables:
	<command>pltcl_loadmod</>, <command>pltcl_listmod</>,
	<command>pltcl_delmod</>, as well as source for the standard
	<literal>unknown</> module in <filename>share/unknown.pltcl</>.  This module
	must be loaded
	into each database initially to support the autoloading mechanism.
d694 2
a695 2
	must be readable by all, but it is wise to make them owned and
	writable only by the database administrator.
@


2.31
log
@Some editorializing on the docs for the dollar-quoting feature: fix
grammar, don't drop discussions into the middle of unrelated discussions,
etc.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql-server/doc/src/sgml/pltcl.sgml,v 2.30 2004/05/16 23:22:07 neilc Exp $
d452 13
a464 11
	Emits a log or error message. Possible levels are
	<literal>DEBUG</>, <literal>LOG</>, <literal>INFO</>,
	<literal>NOTICE</>, <literal>WARNING</>, <literal>ERROR</>, and
	<literal>FATAL</>. Most simply emit the given message just like
	the <literal>elog</> C function. <literal>ERROR</>
	raises an error condition: further execution of the function is
	abandoned, and the current transaction is aborted.
	<literal>FATAL</> aborts the transaction and causes the current
	session to shut down.  (There is probably no good reason to use
	this error level in PL/Tcl functions, but it's provided for
	completeness.)
@


2.30
log
@Add documentation for the new "dollar quoting" feature, and update existing
examples to use dollar quoting when appropriate. Original patch from David
Fetter, additional work and editorializing by Neil Conway.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql-server/doc/src/sgml/pltcl.sgml,v 2.29 2004/01/24 23:06:29 tgl Exp $
d403 1
a403 1
	Duplicates all occurrences of single quote and backslash characters
d425 1
a425 1
	The submitted command should contain
d428 1
a428 1
SELECT $q$doesn't$q$ AS ret
@


2.29
log
@Fix problems with dropped columns in pltcl triggers, per report from Patrick Samson.
@
text
@d2 1
a2 1
$PostgreSQL: pgsql-server/doc/src/sgml/pltcl.sgml,v 2.28 2003/11/29 19:51:37 pgsql Exp $
d80 2
a81 1
CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS '
d83 1
a83 1
' LANGUAGE pltcl;
d104 1
a104 1
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS '
d107 1
a107 1
' LANGUAGE pltcl STRICT;
d126 1
a126 1
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS '
d134 1
a134 1
' LANGUAGE pltcl;
d158 1
a158 1
CREATE FUNCTION overpaid(employee) RETURNS boolean AS '
d166 1
a166 1
' LANGUAGE pltcl;
d363 1
a363 1
CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS '
d366 2
a367 2
        set GD(plan) [ spi_prepare \\
                "SELECT count(*) AS cnt FROM t1 WHERE num &gt;= \\$1 AND num &lt;= \\$2" \\
d372 1
a372 1
' LANGUAGE pltcl;
d375 6
a380 7
	Note that each backslash that Tcl should see must be doubled when
	we type in the function, since the main parser processes
	backslashes, too, in <command>CREATE FUNCTION</>.  We need backslashes inside
	the query string given to <function>spi_prepare</> to ensure that
	the <literal>$<replaceable>n</replaceable></> markers will be passed through to
	<function>spi_prepare</> as-is, and not
	replaced by Tcl variable substitution.
d428 1
a428 1
SELECT 'doesn''t' AS ret
d614 1
a614 1
CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS '
d628 1
a628 1
' LANGUAGE pltcl;
@


2.28
log
@
$Header: -> $PostgreSQL Changes ...
@
text
@d2 1
a2 1
$PostgreSQL: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.27 2003/11/12 22:47:47 petere Exp $
d519 4
a522 1
	 numbered in <productname>PostgreSQL</productname>.
@


2.27
log
@Documentation cleanup
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.26 2003/09/08 23:02:28 petere Exp $
@


2.26
log
@Update preface.

Use question marks rather than brackets to delimit optional elements in
Tcl synopses.

Fix stylesheet misfeature leading to excessively long cross-reference text
when linking to a different "part".

Remove <body> attributes -- CSS stylesheets should handle that.

Improve bibliography formatting.

Add fast-forward links for more convenient navigation.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.25 2003/08/31 17:32:19 petere Exp $
d139 1
a139 1
     to return a NULL value from a PL/Tcl function, execute
@


2.26.2.1
log
@Documentation cleanup
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.26 2003/09/08 23:02:28 petere Exp $
d139 1
a139 1
     to return a null value from a PL/Tcl function, execute
@


2.26.2.2
log
@Fix problems with dropped columns in pltcl triggers, per report from Patrick Samson.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.26.2.1 2003/11/12 20:05:14 petere Exp $
d519 1
a519 4
	 numbered in <productname>PostgreSQL</productname>.  (Empty list
	 elements also appear in the positions of columns that have been
	 dropped, so that the attribute numbering is correct for columns
	 to their right.)
@


2.26.2.3
log
@Prevent PL/Tcl from loading the "unknown" module from pltcl_modules unless
that is a regular table or view owned by a superuser.  This prevents a
trojan horse attack whereby any unprivileged SQL user could create such a
table and insert code into it that would then get executed in other users'
sessions whenever they call pltcl functions.

Worse yet, because the code was automatically loaded into both the "normal"
and "safe" interpreters at first use, the attacker could execute unrestricted
Tcl code in the "normal" interpreter without there being any pltclu functions
anywhere, or indeed anyone else using pltcl at all: installing pltcl is
sufficient to open the hole.  Change the initialization logic so that the
"unknown" code is only loaded into an interpreter when the interpreter is
first really used.  (That doesn't add any additional security in this
particular context, but it seems a prudent change, and anyway the former
behavior violated the principle of least astonishment.)

Security: CVE-2010-1170
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.26.2.2 2004/01/24 23:06:41 tgl Exp $
d649 2
a650 4
	and loaded into the Tcl interpreter immediately before the first
	execution of a PL/Tcl function in a database session.  (This
	happens separately for PL/Tcl and PL/TclU, if both are used,
	because separate interpreters are used for the two languages.)
d653 1
a653 1
	While the <literal>unknown</> module could actually contain any
d666 1
a666 1
	The <productname>PostgreSQL</productname> distribution includes
d670 1
a670 1
	<literal>unknown</> module in <filename>share/unknown.pltcl</>.	 This module
d675 1
a675 1
	The tables <literal>pltcl_modules</> and <literal>pltcl_modfuncs</>
d677 1
a677 5
	writable only by the database administrator.  As a security
	precaution, PL/Tcl will ignore <literal>pltcl_modules</> (and thus,
	not attempt to load the <literal>unknown</> module) unless it is
	owned by a superuser.  But update privileges on this table can be
	granted to other users, if you trust them sufficiently.
@


2.25
log
@Add/edit index entries.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.24 2003/06/22 16:17:00 tgl Exp $
d238 1
a238 1
      <term><function>spi_exec</function> <literal>?-count <replaceable>n</replaceable>? ?-array <replaceable>name</replaceable>? <replaceable>command</replaceable> ?<replaceable>loop-body</replaceable>?</literal></term>
d332 1
a332 1
      <term><function>spi_execp</> <literal>?-count <replaceable>n</replaceable>? ?-array <replaceable>name</replaceable>? ?-nulls <replaceable>string</replaceable>? <replaceable>queryid</replaceable> ?<replaceable>value-list</replaceable>? ?<replaceable>loop-body</replaceable>?</literal></term>
@


2.24
log
@Fix some index entries.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.23 2003/04/07 01:29:25 petere Exp $
d193 5
d306 4
a309 2
	Prepares and saves a query plan for later execution.  The saved plan
	will be retained for the life of the current session.
d447 1
a447 1
       <secondary>PL/Tcl</secondary>
d476 1
a476 1
     <primary>triggers</primary>
@


2.24.2.1
log
@Update this branch to match CVS head, includes WIN32 improvements.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.25 2003/08/31 17:32:19 petere Exp $
a192 5
    <indexterm zone="pltcl-global">
     <primary>global data</primary>
     <secondary>in PL/Tcl</secondary>
    </indexterm>

d301 2
a302 4
	Prepares and saves a query plan for later execution.  The
	saved plan will be retained for the life of the current
	session.<indexterm><primary>preparing a query</><secondary>in
	PL/Tcl</></>
d440 1
a440 1
       <secondary>in PL/Tcl</secondary>
d469 1
a469 1
     <primary>trigger</primary>
@


2.23
log
@General editing
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.22 2002/09/21 18:32:53 petere Exp $
d440 1
@


2.22
log
@Add more appropriate markup.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.21 2002/08/22 00:01:40 tgl Exp $
a22 4
  <para>
   This package was originally written by Jan Wieck.
  </para>

d37 2
a38 2
    database backend or to gain OS-level access under the permissions of the
    <productname>PostgreSQL</productname> user ID, as a C function can do.
d43 1
a43 1
    The other, implementation restriction is that Tcl procedures cannot
d48 2
a49 2
    to safe Tcl --- for example, one might want a Tcl function that sends
    mail.  To handle these cases, there is a variant of <application>PL/Tcl</> called <literal>PL/TclU</>
d65 1
a65 1
    <filename>createlang</filename> script, for example
d73 1
a73 4
  <sect1 id="pltcl-description">
   <title>Description</title>

   <sect2>
d77 1
a77 1
     To create a function in the <application>PL/Tcl</> language, use the standard syntax
d79 1
a79 1
     <programlisting>
d82 2
a83 2
' LANGUAGE 'pltcl';
     </programlisting>
d85 1
a85 1
     <application>PL/TclU</> is the same, except that the language should be specified as
d92 1
a92 1
     variables <literal>$1</literal> ... <literal>$n</literal> to the
d95 5
a99 1
     statement.  For example, a function
d102 2
a103 2
     <programlisting>
CREATE FUNCTION tcl_max (integer, integer) RETURNS integer AS '
d106 2
a107 2
' LANGUAGE 'pltcl' WITH (isStrict);
     </programlisting>
d109 3
a111 3
     Note the clause <literal>WITH (isStrict)</>, which saves us from
     having to think about NULL input values: if a NULL is passed, the
     function will not be called at all, but will just return a NULL
d116 4
a119 4
     In a non-strict function,
     if the actual value of an argument is NULL, the corresponding
     <literal>$n</literal> variable will be set to an empty string.
     To detect whether a particular argument is NULL, use the function
d121 2
a122 2
     with one null and one non-null argument to return the non-null
     argument, rather than NULL:
d124 2
a125 2
     <programlisting>
CREATE FUNCTION tcl_max (integer, integer) RETURNS integer AS '
d133 2
a134 2
' LANGUAGE 'pltcl';
     </programlisting>
d145 11
a155 6
     Composite-type arguments are passed to the procedure as Tcl arrays.
     The element names of the array are the attribute names of the composite
     type. If an attribute in the passed row
     has the NULL value, it will not appear in the array! Here is
     an example that defines the overpaid_2 function (as found in the
     older <productname>PostgreSQL</productname> documentation) in PL/Tcl:
d157 1
a157 2
     <programlisting>
CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
d165 2
a166 2
' LANGUAGE 'pltcl';
     </programlisting>
d170 1
a170 1
     There is not currently any support for returning a composite-type
d174 1
a174 1
   </sect2>
d176 1
a176 1
   <sect2>
d180 1
a180 1
     The argument values supplied to a PL/Tcl function's script are simply
d182 1
a182 1
     displayed by a SELECT statement).  Conversely, the <literal>return</>
d188 1
a188 1
   </sect2>
d190 1
a190 1
   <sect2>
d195 2
a196 2
     is useful to have some global status data that is held between two
     calls to a procedure or is shared between different procedures.
d198 1
a198 1
     all PL/Tcl procedures executed in one backend share the same
d200 2
a201 2
     all PL/Tcl procedure calls, and will persist for the duration of the
     SQL client connection.  (Note that <application>PL/TclU</> functions likewise share
d206 1
a206 1
     To help protect PL/Tcl procedures from unintentionally interfering
d208 3
a210 3
     array is made available to each procedure via the <function>upvar</>
     command. The global name of this variable is the procedure's internal
     name and the local name is <literal>GD</>.  It is recommended that
d212 1
a212 1
     for private status data of a procedure.  Use regular Tcl global variables
d214 1
a214 1
     procedures.
d221 1
a221 1
   </sect2>
d223 1
a223 1
   <sect2>
d228 1
a228 2
     the body of a PL/Tcl procedure:
    </para>
d233 1
a233 1
      <term><function>spi_exec</function> <literal>?-count <replaceable>n</replaceable>? ?-array <replaceable>name</replaceable>? <replaceable>query</replaceable> ?<replaceable>loop-body</replaceable>?</literal></term>
d236 2
a237 2
	Execute an SQL query given as a string.  An error in the query
	causes an error to be raised.  Otherwise, the command's return value
d239 2
a240 2
	deleted) by the query, or zero if the query is a utility
	statement.  In addition, if the query is a SELECT statement, the
d247 2
a248 2
	to process in the query.  The effect of this is comparable to
	setting up the query as a cursor and then saying <literal>FETCH n</>.
d251 1
a251 1
	If the query is a <literal>SELECT</> statement, the values of the statement's
d254 1
a254 1
	instead stored into the named associative array, with the SELECT
d258 1
a258 1
        If the query is a SELECT statement and no <replaceable>loop-body</>
d260 1
a260 1
	Tcl variables; remaining rows, if any, are ignored.  No store occurs
d262 2
a263 2
	SELECT returns no rows (this case can be detected by checking the
	result of <function>spi_exec</function>).  For example,
d265 1
a265 1
	<programlisting>
d267 1
a267 1
	</programlisting>
d275 2
a276 2
	SELECT result (note: <replaceable>loop-body</> is ignored if the given
	query is not a SELECT).  The values of the current row's fields
d279 1
a279 1
	<programlisting>
d283 1
a283 1
	</programlisting>
d285 1
a285 1
	will print a DEBUG log message for every row of pg_class.  This
d291 1
a291 1
        If a field of a SELECT result is NULL, the target
d302 1
a302 1
	will be retained for the life of the current backend.
d305 1
a305 1
        The query may use <firstterm>arguments</>, which are placeholders for
d307 3
a309 3
	In the query string, refer to arguments
	by the symbols <literal>$1</literal> ... <literal>$n</literal>.
	If the query uses arguments, the names of the argument types
d311 3
a313 3
	<replaceable>typelist</replaceable> if no arguments are used.)
	Presently, the argument types must be identified by the internal
	type names shown in pg_type; for example <literal>int4</> not
d328 1
a328 1
	Execute a query previously prepared with <function>spi_prepare</>.
d330 4
a333 4
	<function>spi_prepare</>.  If the query references arguments,
	a <replaceable>value-list</replaceable> must be supplied: this
	is a Tcl list of actual values for the arguments.  This must be
	the same length as the argument type list previously given to
d335 1
a335 1
	if the query has no arguments.
d340 1
a340 1
	which of the arguments are null values. If given, it must have exactly the
d342 1
a342 1
	is not given, all the argument values are non-NULL.
d345 1
a345 1
        Except for the way in which the query and its arguments are specified,
d354 1
a354 1
	<programlisting>
d364 2
a365 2
' LANGUAGE 'pltcl';
	</programlisting>
d369 1
a369 1
	backslashes too in CREATE FUNCTION.  We need backslashes inside
d371 1
a371 1
	the <literal>$n</> markers will be passed through to
d386 2
a387 2
	<function>spi_exec</>'d or <function>spi_execp</>'d query,
	if that query was a single-row INSERT.  (If not, you get zero.)
d398 1
a398 1
	that are to be inserted into SQL queries given
d401 1
a401 1
	For example, think about a query string like
d407 1
a407 1
	where the Tcl variable val actually contains
d409 1
a409 1
	in the final query string
d418 1
a418 1
	The submitted query should contain
d424 1
a424 1
	which can be formed in PL/Tcl as
d431 2
a432 2
	have to quote argument values like this, since the arguments are never
	parsed as part of an SQL query string.
d444 1
a444 1
	Emit a log or error message. Possible levels are
d448 1
a448 1
	the <literal>elog</> backend C function. <literal>ERROR</>
d452 1
a452 1
	backend to shut down (there is probably no good reason to use
d454 1
a454 1
	completeness).
d460 1
d462 1
a462 1
   </sect2>
d464 1
a464 1
   <sect2>
d473 2
a474 2
     Trigger procedures can be written in PL/Tcl.  As is customary in
     <productname>PostgreSQL</productname>, a procedure that's to be called
d485 1
a485 1
       <term><replaceable class="Parameter">$TG_name</replaceable></term>
d488 1
a488 1
	 The name of the trigger from the CREATE TRIGGER statement.
d494 1
a494 1
       <term><replaceable class="Parameter">$TG_relid</replaceable></term>
d504 1
a504 1
       <term><replaceable class="Parameter">$TG_relatts</replaceable></term>
d507 2
a508 2
	 A Tcl list of the table field names, prefixed with an empty list
         element. So looking up an element name in the list with <application>Tcl</>'s
d510 1
a510 1
	 with 1 for the first column, the same way the fields are customarily
d517 1
a517 1
       <term><replaceable class="Parameter">$TG_when</replaceable></term>
d527 1
a527 1
       <term><replaceable class="Parameter">$TG_level</replaceable></term>
d537 1
a537 1
       <term><replaceable class="Parameter">$TG_op</replaceable></term>
d540 1
a540 1
	 The string <literal>INSERT</>, <literal>UPDATE</> or
d547 1
a547 1
       <term><replaceable class="Parameter">$NEW</replaceable></term>
d550 4
a553 3
	 An associative array containing the values of the new table row for
	 INSERT/UPDATE actions, or empty for DELETE.  The array is indexed
	 by field name.  Fields that are NULL will not appear in the array!
d559 1
a559 1
       <term><replaceable class="Parameter">$OLD</replaceable></term>
d562 4
a565 3
	 An associative array containing the values of the old table row for
	 UPDATE/DELETE actions, or empty for INSERT.  The array is indexed
	 by field name.  Fields that are NULL will not appear in the array!
d571 1
a571 1
       <term><replaceable class="Parameter">$args</replaceable></term>
d575 2
a576 2
	 CREATE TRIGGER statement. These arguments are also accessible as
	 <literal>$1</literal> ... <literal>$n</literal> in the procedure body.
d588 1
a588 1
     the operation (INSERT/UPDATE/DELETE) that fired the trigger will proceed
d592 3
a594 3
     instead of the one given in $NEW (this works for INSERT/UPDATE
     only). Needless to say that all this is only meaningful when the trigger
     is BEFORE and FOR EACH ROW; otherwise the return value is ignored.
d600 1
a600 1
     incremented on every update operation:
d602 2
a603 2
     <programlisting>
CREATE FUNCTION trigfunc_modcount() RETURNS TRIGGER AS '
d617 1
a617 1
' LANGUAGE 'pltcl';
d623 1
a623 1
     </programlisting>
d627 1
a627 1
     trigger procedure be re-used with different tables.
d629 1
a629 1
   </sect2>
d631 2
a632 2
   <sect2>
       <title> Modules and the <function>unknown</> command</title>
d634 1
a634 1
	PL/Tcl has support for auto-loading Tcl code when used.
d644 1
a644 1
	<quote>unknown</> procedure that is invoked whenever Tcl does
d659 1
a659 1
	unknown module <filename>share/unknown.pltcl</>.  This module
d668 1
a668 1
   </sect2>
d670 1
a670 1
   <sect2>
d680 1
a680 1
     ID of the procedure's <structname>pg_proc</> row as part of their name. Thus,
d682 1
a682 1
     and different argument types will be different Tcl procedures too.  This
d687 1
a687 3
   </sect2>

  </sect1>
@


2.21
log
@Add a bunch of pseudo-types to replace the behavior formerly associated
with OPAQUE, as per recent pghackers discussion.  I still want to do some
more work on the 'cstring' pseudo-type, but I'm going to commit the bulk
of the changes now before the tree starts shifting under me ...
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql-server/doc/src/sgml/pltcl.sgml,v 2.20 2002/03/22 19:20:21 petere Exp $
d53 1
a53 1
    mail.  To handle these cases, there is a variant of PL/Tcl called PL/TclU
d55 1
a55 1
    Tcl interpreter is used.  <emphasis>If PL/TclU is used, it must be
d57 1
a57 1
    database superusers can create functions in it.  The writer of a PL/TclU
d63 1
a63 1
    The shared object for the PL/Tcl and PL/TclU call handlers is
d68 1
a68 1
    PL/Tcl and/or PL/TclU in a particular database, use the
d84 1
a84 1
     To create a function in the PL/Tcl language, use the standard syntax
d92 2
a93 2
     PL/TclU is the same, except that the language should be specified as
     <literal>'pltclu'</>.
d200 1
a200 1
     SQL client connection.  (Note that PL/TclU functions likewise share
d251 1
a251 1
	If the query is a SELECT statement, the values of the SELECT's
d270 1
a270 1
	the pg_proc system catalog.
d340 1
a340 1
	which of the arguments are NULLs. If given, it must have exactly the
d507 1
a507 1
         element. So looking up an element name in the list with Tcl's
d642 1
a642 1
	not recognize an invoked procedure name.  PL/Tcl's standard version
d677 1
a677 1
     ID of the procedure's pg_proc row as part of their name. Thus,
@


2.20
log
@Spell checking and markup additions
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.19 2002/03/06 19:05:58 momjian Exp $
d475 1
a475 1
     and a return type of <literal>opaque</>.
d600 1
a600 1
CREATE FUNCTION trigfunc_modcount() RETURNS OPAQUE AS '
@


2.19
log
@Update docs for new stored procedure error levels.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.18 2002/01/23 21:08:17 tgl Exp $
d123 1
a123 1
     <literal>argisnull</>.  For example, suppose that we wanted tcl_max
@


2.18
log
@Overhaul PL/Tcl documentation.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.17 2001/11/21 05:53:41 thomas Exp $
d444 11
a454 10
	Emit a log or error message. Possible levels are <literal>DEBUG</>,
	<literal>NOTICE</>, <literal>ERROR</>, and <literal>FATAL</>.
	<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.  <literal>FATAL</> aborts the transaction and
	causes the current backend to shut down (there is probably no good
	reason to use this error level in PL/Tcl functions, but it's provided
	for completeness).
@


2.17
log
@Deprecate 'current' for date/time input.
Fix up references to "PostgreSQL" rather than "Postgres". Was roughly
 evenly split between the two before. ref/ files not yet done.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.16 2001/11/19 03:58:24 tgl Exp $
d19 1
a19 1
   that enables the Tcl language to be used to create functions and
d69 3
a71 1
    <filename>createlang</filename> script.
d81 1
a81 17
    <title><productname>PostgreSQL</productname> Functions and Tcl Procedure Names</title>

    <para>
     In <productname>PostgreSQL</productname>, one and the 
     same function name can be used for
     different functions as long as the number of arguments or their types
     differ. This would collide with Tcl procedure names. To offer the same
     flexibility in PL/Tcl, the internal Tcl procedure names contain the object
     ID of the procedure's pg_proc row as part of their name. Thus, different
     argtype versions of the same <productname>PostgreSQL</productname> 
     function are different for Tcl too.
    </para>

   </sect2>

   <sect2>
    <title>Defining Functions in PL/Tcl</title>
d92 7
a98 1
     When the function is called, the arguments are given as
d100 1
a100 1
     Tcl procedure body.  The result is returned
d103 1
a103 1
     returning the higher of two int4 values could be defined as:
d106 28
a133 1
CREATE FUNCTION tcl_max (int4, int4) RETURNS int4 AS '
d138 1
d140 5
a144 2
     To return a NULL value from a PL/Tcl function, execute
     <literal>return_null</literal>.
d148 3
a150 4
     Composite type arguments are given to the procedure as Tcl arrays.
     The element names
     in the array are the attribute names of the composite
     type. If an attribute in the actual row
d153 1
a153 1
     older <productname>PostgreSQL</productname> documentation) in PL/Tcl
d168 19
d193 1
a193 1
     Sometimes (especially when using the SPI functions described later) it
d195 2
a196 1
     calls to a procedure.  This is easily done since
d198 5
a202 1
     safe Tcl interpreter.
d205 3
a207 2
     To help protect PL/Tcl procedures from unwanted side effects,
     an array is made available to each procedure via the <function>upvar</>
d209 2
a210 1
     name and the local name is GD.  It is recommended that GD be used
d215 245
d471 4
a474 4
     Trigger procedures are defined in <productname>PostgreSQL</productname>
     as functions without
     arguments and a return type of opaque. And so are they in the PL/Tcl
     language.
d477 1
a477 1
     The information from the trigger manager is given to the procedure body
d505 5
a509 4
	 A Tcl list of the tables field names prefixed with an empty list element.
	 So looking up an element name in the list with the <function>lsearch</> Tcl command
	 returns the same positive number starting from 1 as the fields are numbered
	 in the pg_attribute system catalog.
d518 2
a519 1
	 The string BEFORE or AFTER depending on the event of the trigger call.
d528 2
a529 1
	 The string ROW or STATEMENT depending on the event of the trigger call.
d538 2
a539 2
	 The string INSERT, UPDATE or DELETE depending on the event of the 
	 trigger call.
d548 3
a550 2
	 An array containing the values of the new table row on INSERT/UPDATE
	 actions, or empty on DELETE.
d559 3
a561 11
	 An array containing the values of the old table row on UPDATE/DELETE
	 actions, or empty on INSERT.
	</para>
       </listitem>
      </varlistentry>

      <varlistentry>
       <term><replaceable class="Parameter">$GD</replaceable></term>
       <listitem>
	<para>
	 The global status data array as described above.
d571 2
a572 2
	 CREATE TRIGGER statement. The arguments are also accessible as $1 ... $n
	 in the procedure body.
d581 10
a590 8
     The return value from a trigger procedure is one of the strings OK or SKIP,
     or a list as returned by the 'array get' Tcl command. If the return value
     is OK, the normal operation (INSERT/UPDATE/DELETE) that fired this trigger
     will take place. Obviously, SKIP tells the trigger manager to silently
     suppress the operation. The list from 'array get' tells PL/Tcl
     to return a modified row to the trigger manager that will be inserted instead
     of the one given in $NEW (INSERT/UPDATE only). Needless to say that all
     this is only meaningful when the trigger is BEFORE and FOR EACH ROW.
d615 1
a615 1
CREATE TABLE mytab (num int4, modcnt int4, description text);
d621 3
d628 1
a628 15
    <title>Database Access from PL/Tcl</title>

    <para>
     The following commands are available to access the database from
     the body of a PL/Tcl procedure:
    </para>

    <variablelist>

     <varlistentry>
      <indexterm>
       <primary>elog</primary>
      </indexterm>
      <term><function>elog</> <replaceable>level</replaceable> <replaceable>msg</replaceable></term>
      <listitem>
d630 33
a662 3
	Fire a log message. Possible levels are NOTICE, ERROR,
	FATAL, and DEBUG
	as for the <function>elog</function> C function.
d664 1
a664 2
      </listitem>
     </varlistentry>
d666 2
a667 10
     <varlistentry>
      <term><function>quote</> <replaceable>string</replaceable></term>
      <listitem>
       <para>
	Duplicates all occurrences of single quote and backslash characters.
	It should be used when variables are used in the query string given
	to <function>spi_exec</function> or
	<function>spi_prepare</function> (not for the value list on
	<function>spi_execp</function>).
	Think about a query string like
d669 13
a681 19
<programlisting>
"SELECT '$val' AS ret"
</programlisting>

	where the Tcl variable val actually contains <literal>doesn't</literal>. This would result
	in the final query string

<programlisting>
SELECT 'doesn't' AS ret
</programlisting>

	which would cause a parse error during
	<function>spi_exec</function> or
	<function>spi_prepare</function>.
	It should contain

<programlisting>
SELECT 'doesn''t' AS ret
</programlisting>
a682 152
	and has to be written as

<programlisting>
SELECT '[ quote $val ]' AS ret
</programlisting>
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <indexterm>
       <primary>spi_lastoid</primary>
      </indexterm>
      <term><function>spi_lastoid</></term>
      <listitem>
       <para>
	Returns the OID of the last query if it was an INSERT.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><function>spi_exec</function> <literal>?-count <replaceable>n</replaceable>? ?-array <replaceable>name</replaceable>? <replaceable>query</replaceable> ?<replaceable>loop-body</replaceable>?</literal></term>
      <listitem>
       <para>
	Call parser/planner/optimizer/executor for query.
	The optional -count value tells <function>spi_exec</function>
	the maximum number of rows
	to be processed by the query.
       </para>
       <para>
	If the query is
	a SELECT statement and the optional loop-body (a body of Tcl commands
	like in a foreach statement) is given, it is evaluated for each
	row selected and behaves like expected on continue/break. The values
	of selected fields are put into variables named as the column names. So a

	<programlisting>
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
	</programlisting>

	will set the variable $cnt to the number of rows in the pg_proc system
	catalog. If the option -array is given, the column values are stored
	in the associative array named 'name' indexed by the column name
	instead of individual variables.

	<programlisting>
spi_exec -array C "SELECT * FROM pg_class" {
    elog DEBUG "have table $C(relname)"
}
	</programlisting>

	will print a DEBUG log message for every row of pg_class. The return value
	of <function>spi_exec</function> is the number of rows
	affected by the query as found in
	the global variable SPI_processed.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><function>spi_prepare</function> <replaceable>query</replaceable> <replaceable>typelist</replaceable></term>
      <listitem>
       <para>
	Prepares AND SAVES a query plan for later execution. It is a bit different
	from the C level SPI_prepare in that the plan is automatically copied to the
	top-level memory context. Thus, there is currently no way of preparing a
	plan without saving it.
       </para>
       <para>
	If the query references arguments, the type names must be given as a Tcl
	list. The return value from <function>spi_prepare</function> is a query ID to be used in
	subsequent calls to <function>spi_execp</function>. See <function>spi_execp</function> for a sample.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><function>spi_execp</> <literal>?-count <replaceable>n</replaceable>? ?-array<replaceable>name</replaceable>? ?-nulls<replaceable>string</replaceable>? <replaceable>queryid</replaceable> ?<replaceable>value-list</replaceable>? ?<replaceable>loop-body</replaceable>?</literal></term>
      <listitem>
       <para>
	Execute a prepared plan from <function>spi_prepare</> with variable substitution.
	The optional <literal>-count</literal> value tells <function>spi_execp</> the maximum number of rows
	to be processed by the query.
       </para>
       <para>
	The optional value for <literal>-nulls</> is a string of spaces and 'n' characters
	telling <function>spi_execp</function> which of the values are NULL's. If given, it must
	have exactly the length of the number of values.
       </para>
       <para>
	The <parameter>queryid</> is the ID returned by the <function>spi_prepare</function> call.
       </para>
       <para>
	If there was a <parameter>typelist</> given to <function>spi_prepare</function>, a Tcl list of values of
	exactly the same length must be given to spi_execp after the query. If
	the type list on spi_prepare was empty, this argument must be omitted.
       </para>
       <para>
	If the query is a SELECT statement, the same as described for <function>spi_exec</>
	happens for the loop-body and the variables for the fields selected.
       </para>
       <para>
	Here's an example for a PL/Tcl function using a prepared plan:

	<programlisting>
CREATE FUNCTION t1_count(int4, int4) RETURNS int4 AS '
    if {![ info exists GD(plan) ]} {
        # prepare the saved plan on the first call
        set GD(plan) [ spi_prepare \\
                "SELECT count(*) AS cnt FROM t1 WHERE num &gt;= \\$1 AND num &lt;= \\$2" \\
                int4 ]
    }
    spi_execp -count 1 $GD(plan) [ list $1 $2 ]
    return $cnt
' LANGUAGE 'pltcl';
	</programlisting>

	Note that each backslash that Tcl should see must be doubled in
	the query creating the function, since the main parser processes
	backslashes too on CREATE FUNCTION.
	Inside the query string given to <function>spi_prepare</> should
	really be dollar signs to mark the parameter positions and to not let
	$1 be substituted by the value given in the first function call.
       </para>
      </listitem>
     </varlistentry>


    </variablelist>

   </sect2>

   <sect2>
       <title> Modules and the <function>unknown</> command</title>
       <para>
	PL/Tcl has a special support for things often used. It
	recognizes two magic tables, <literal>pltcl_modules</> and
	<literal>pltcl_modfuncs</>.  If these exist, the module
	'unknown' is loaded into the interpreter right after
	creation. Whenever an unknown Tcl procedure is called, the
	unknown proc is asked to check if the procedure is defined in
	one of the modules. If this is true, the module is loaded on
	demand.
       </para>
       <para>
	There are support scripts to maintain these tables:
	<command>pltcl_loadmod</>,<command>pltcl_listmod</>,
	<command>pltcl_delmod</> and source for the
	unknown module <filename>share/unknown.pltcl</> that must be loaded
	into database initially for getting unknown support.
       </para>
@


2.16
log
@A bunch of small doco updates motivated by scanning the comments on
the interactive docs.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.15 2001/10/13 04:23:50 momjian Exp $
d18 1
a18 1
   <productname>Postgres</productname> database system
d42 1
a42 1
    <productname>Postgres</productname> user ID, as a C function can do.
d65 1
a65 1
    <productname>Postgres</productname> 
d79 1
a79 1
    <title><productname>Postgres</productname> Functions and Tcl Procedure Names</title>
d82 1
a82 1
     In <productname>Postgres</productname>, one and the 
d88 1
a88 1
     argtype versions of the same <productname>Postgres</productname> 
d131 1
a131 1
     older <productname>Postgres</productname> documentation) in PL/Tcl
d178 1
a178 1
     Trigger procedures are defined in <productname>Postgres</productname>
@


2.15
log
@Attached patch for unconditional enabling of pltcl-unknown support.

Enabling this feature adds very light overhead of 1 select from pg_class on
first using of pl/tcl in backend if unknown suppport is really unused.
But pl/tcl with this support has very improved functionality.

Patch includes changes to documentation.
@
text
@d2 1
a2 1
$Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.14 2001/09/13 15:55:23 petere Exp $
d466 1
a466 1
      <term><function>spi_exec</> <literal>?-count <replaceable>n</replaceable>? ?-array<replaceable>name</replaceable>? ?-nulls<replaceable>string</replaceable>? <replaceable>queryid</replaceable> ?<replaceable>value-list</replaceable>? ?<replaceable>loop-body</replaceable>?</literal></term>
@


2.14
log
@Replace ASCII-quotes with proper markup.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.13 2001/09/10 21:58:47 petere Exp $
d516 7
a522 5
     <varlistentry>
      <term>
       Modules and the <function>unknown</> command
      </term>
      <listitem>
d531 1
a531 3
	demand.  To enable this behavior, the
	<productname>PostgreSQL</> must be configured with the option
	<option>--enable-pltcl-unknown</option>.
d534 5
a538 3
	There are support scripts to maintain these tables in the modules
	subdirectory of the PL/Tcl source including the source for the
	unknown module that must get installed initially.
a539 5
      </listitem>
     </varlistentry>

    </variablelist>

@


2.13
log
@Markup and spell-check run over Programmer's Guide (rather incomplete still).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.12 2001/08/02 15:45:55 momjian Exp $
d368 1
a368 1
	<programlisting>
d370 1
a370 1
	</programlisting>
d372 1
a372 1
	where the Tcl variable val actually contains "doesn't". This would result
d375 3
a377 3
	<programlisting>
"SELECT 'doesn't' AS ret"
	</programlisting>
d384 3
a386 3
	<programlisting>
"SELECT 'doesn''t' AS ret"
	</programlisting>
d390 3
a392 3
	<programlisting>
"SELECT '[ quote $val ]' AS ret"
	</programlisting>
@


2.12
log
@I noticed that pltcl didn't have any way to get to SPI_lastoid like plpgsql does.. I started using pltcl a lot because I like to decide when and how my queries get planned.. so I put one together really quick

Sorry I don't have the original around to make a quick diff, but its a very small change... I think this should be in the next release, there's no reason not to have it.

its a function with no expected arguments, so you can use it like:
spi_exec "INSERT INTO mytable(columns...) VALUES(values..)"
set oid [spi_lastoid]
spi_exec "SELECT mytable_id from mytable WHERE oid=$oid"

It just didn't make sense for me to use plpgsql and pltcl, or just screw
them both and use SPI from C.


bob@@redivi.com
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.11 2001/06/09 02:19:07 tgl Exp $
d6 1
a6 1
  <title>PL/Tcl - TCL Procedural Language</title>
d40 1
a40 1
    messages via elog(). There is no way to access internals of the
d160 1
a160 1
     an array is made available to each procedure via the upvar
d213 1
a213 1
	 So looking up an element name in the list with the lsearch Tcl command
d347 1
a347 1
      <term>elog <replaceable>level</replaceable> <replaceable>msg</replaceable></term>
d358 1
a358 1
      <term>quote <replaceable>string</replaceable></term>
d401 1
a401 1
      <term>spi_lastoid</term>
d410 1
a410 1
      <term>spi_exec ?-count <replaceable>n</replaceable>? ?-array <replaceable>name</replaceable>? <replaceable>query</replaceable> ?<replaceable>loop-body</replaceable>?</term>
d449 1
a449 1
      <term>spi_prepare <replaceable>query</replaceable> <replaceable>typelist</replaceable></term>
d454 1
a454 1
	toplevel memory context. Thus, there is currently no way of preparing a
d459 2
a460 2
	list. The return value from spi_prepare is a query ID to be used in
	subsequent calls to spi_execp. See spi_execp for a sample.
d466 1
a466 1
      <term>spi_exec ?-count <replaceable>n</replaceable>? ?-array<replaceable>name</replaceable>? ?-nulls<replaceable>string</replaceable>? <replaceable>queryid</replaceable> ?<replaceable>value-list</replaceable>? ?<replaceable>loop-body</replaceable>?</term>
d469 2
a470 2
	Execute a prepared plan from spi_prepare with variable substitution.
	The optional -count value tells spi_execp the maximum number of rows
d474 2
a475 2
	The optional value for -nulls is a string of spaces and 'n' characters
	telling spi_execp which of the values are NULL's. If given, it must
d479 1
a479 1
	The queryid is the ID returned by the spi_prepare call.
d482 1
a482 1
	If there was a typelist given to spi_prepare, a Tcl list of values of
d487 1
a487 1
	If the query is a SELECT statement, the same as described for spi_exec
d509 1
a509 1
	Inside the query string given to spi_prepare should
d518 1
a518 1
       Modules and the unknown command
d522 10
a531 8
	PL/Tcl has a special support for things often used. It recognizes two
	magic tables, pltcl_modules and pltcl_modfuncs.
	If these exist, the module 'unknown' is loaded into the interpreter
	right after creation. Whenever an unknown Tcl procedure is called,
	the unknown proc is asked to check if the procedure is defined in one
	of the modules. If this is true, the module is loaded on demand.
	To enable this behavior, the PL/Tcl call handler must be compiled
	with -DPLTCL_UNKNOWN_SUPPORT set.
@


2.11
log
@Fix a few missed NOIND usages.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.10 2001/05/12 22:51:35 petere Exp $
d393 12
@


2.10
log
@Add index.  Only some parts of the manual set have index entries so far...
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.9 2001/04/30 22:22:34 tgl Exp $
d351 1
a351 1
	FATAL, DEBUG and NOIND
@


2.9
log
@Document pltcl's return_null command.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.8 2001/03/25 10:16:12 petere Exp $
d8 8
d172 5
d344 3
@


2.8
log
@spell fix
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.7 2001/02/09 03:06:38 tgl Exp $
d99 4
a102 2
     variables $1 ... $n to the Tcl procedure body.  For example,
     a function
d112 5
@


2.7
log
@Document PL/TclU language variant, and do some minor copy-editing.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere Exp $
d338 1
a338 1
	Duplicates all occurences of single quote and backslash characters.
@


2.6
log
@Add `id' attributes to all `chapter' and `sect1' tags, to generate useful
names for the HTML files (e.g., not x4856.htm).
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.5 2000/08/25 15:17:36 thomas Exp $
d12 1
a12 1
   trigger-procedures.
d29 3
a31 3
    The good restriction is, that everything is executed in a safe
    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
d33 2
a34 2
    database backend or gaining OS-level access under the permissions of the
    <productname>Postgres</productname> user ID like in C.
d39 2
a40 2
    The other, internal given, restriction is, that Tcl procedures cannot
    be used to create input-/output-functions for new data types.
d43 19
a61 4
    The shared object for the PL/Tcl call handler is automatically built
    and installed in the <productname>Postgres</productname>
    library directory if the Tcl/Tk support is specified
    in the configuration step of the installation procedure.
d79 1
a79 1
     ID of the procedures pg_proc row as part of their name. Thus, different
d90 1
a90 1
     To create a function in the PL/Tcl language, use the known syntax
d93 1
a93 1
CREATE FUNCTION <replaceable>funcname</replaceable> <replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS '
d98 4
a101 3
     When calling this function in a query, the arguments are given as
     variables $1 ... $n to the Tcl procedure body. So a little max function
     returning the higher of two int4 values would be created as:
d139 2
a140 2
     calls to a procedure. 
     All PL/Tcl procedures executed in one backend share the same
d142 3
a144 1
     To help protecting PL/Tcl procedures from side effects,
d146 5
a150 2
     command. The global name of this variable is the procedures internal
     name and the local name is GD.
d164 1
a164 1
     The informations from the trigger manager are given to the procedure body
d283 2
a284 2
     in a table to keep track of the # of updates that are performed on the
     row. For new row's inserted, the value is initialized to 0 and then
d329 1
a329 1
	like for the <function>elog</function> C function.
d356 1
a356 1
	what would cause a parse error during
@


2.5
log
@Fix typos and inconsistancies found by He Weiping
 (aka Henry) <laser@@zhangmai.com.cn>.
Fix new problems in insert.sgml and create_function.sgml which kept jade
 from completing.
@
text
@d2 1
a2 1
$Header: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.4 2000/05/18 14:24:32 momjian Exp $
d5 1
a5 1
 <chapter>
d21 1
a21 1
  <sect1>
d52 1
a52 1
  <sect1>
@


2.4
log
@Fix WARN->NOTICE in docs.  Change libpgeasy connection parameters to use
PQconnectdb() style connections.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.3 2000/03/31 06:17:21 thomas Exp $
d283 1
a283 1
CREATE TABLE mytab (num int4, modcnt int4, desc text);
d386 1
a386 1
	affected by query as found in
d410 1
a410 1
      <term>spi_exec ?-count <replaceable>n</replaceable>? ?-array<replaceable>name</replaceable>? ?-nulls<replaceable>string</replaceable>? <replaceable>query</replaceable> ?<replaceable>value-list</replaceable>? ?<replaceable>loop-body</replaceable>?</term>
@


2.3
log
@Use a uniform chapter title for all of the procedural languages.
@
text
@d2 1
a2 1
$Header: /usr/local/cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.2 2000/03/31 03:27:41 thomas Exp $
d306 1
a306 1
	Fire a log message. Possible levels are NOTICE, WARN, ERROR,
@


2.2
log
@Minor markup changes. Refer to (".../catalog") in the emacs hints.
@
text
@d2 1
a2 1
$Header$
d6 1
a6 1
  <title>PL/Tcl</title>
@


2.1
log
@Split off language-specific docs to their own chapters.
Add PL/perl docs from Mark Hollomon.
Put language-specific docs into the User's Guide, and move the rest
 to the Programmer's Guide.
@
text
@d1 4
d502 1
a502 1
sgml-local-catalogs:("/usr/lib/sgml/CATALOG")
@
