1
1
<!--
2
- $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere Exp $
2
+ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.7 2001/02/09 03:06:38 tgl Exp $
3
3
-->
4
4
5
5
<chapter id="pltcl">
@@ -9,7 +9,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
9
9
PL/Tcl is a loadable procedural language for the
10
10
<productname>Postgres</productname> database system
11
11
that enables the Tcl language to be used to create functions and
12
- trigger- procedures.
12
+ trigger procedures.
13
13
</para>
14
14
15
15
<para>
@@ -26,24 +26,39 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
26
26
writer has in the C language, except for some restrictions.
27
27
</para>
28
28
<para>
29
- The good restriction is, that everything is executed in a safe
30
- Tcl- interpreter. In addition to the limited command set of safe Tcl, only
31
- a few commands are available to access the database over SPI and to raise
29
+ The good restriction is that everything is executed in a safe
30
+ Tcl interpreter. In addition to the limited command set of safe Tcl, only
31
+ a few commands are available to access the database via SPI and to raise
32
32
messages via elog(). There is no way to access internals of the
33
- database backend or gaining OS-level access under the permissions of the
34
- <productname>Postgres</productname> user ID like in C .
33
+ database backend or to gain OS-level access under the permissions of the
34
+ <productname>Postgres</productname> user ID, as a C function can do .
35
35
Thus, any unprivileged database user may be
36
36
permitted to use this language.
37
37
</para>
38
38
<para>
39
- The other, internal given, restriction is, that Tcl procedures cannot
40
- be used to create input- /output- functions for new data types.
39
+ The other, implementation restriction is that Tcl procedures cannot
40
+ be used to create input/output functions for new data types.
41
41
</para>
42
42
<para>
43
- The shared object for the PL/Tcl call handler is automatically built
44
- and installed in the <productname>Postgres</productname>
45
- library directory if the Tcl/Tk support is specified
46
- in the configuration step of the installation procedure.
43
+ Sometimes it is desirable to write Tcl functions that are not restricted
44
+ to safe Tcl --- for example, one might want a Tcl function that sends
45
+ mail. To handle these cases, there is a variant of PL/Tcl called PL/TclU
46
+ (for untrusted Tcl). This is the exact same language except that a full
47
+ Tcl interpreter is used. <emphasis>If PL/TclU is used, it must be
48
+ installed as an untrusted procedural language</emphasis> so that only
49
+ database superusers can create functions in it. The writer of a PL/TclU
50
+ function must take care that the function cannot be used to do anything
51
+ unwanted, since it will be able to do anything that could be done by
52
+ a user logged in as the database administrator.
53
+ </para>
54
+ <para>
55
+ The shared object for the PL/Tcl and PL/TclU call handlers is
56
+ automatically built and installed in the
57
+ <productname>Postgres</productname>
58
+ library directory if Tcl/Tk support is specified
59
+ in the configuration step of the installation procedure. To install
60
+ PL/Tcl and/or PL/TclU in a particular database, use the
61
+ <filename>createlang</filename> script.
47
62
</para>
48
63
</sect1>
49
64
@@ -61,7 +76,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
61
76
different functions as long as the number of arguments or their types
62
77
differ. This would collide with Tcl procedure names. To offer the same
63
78
flexibility in PL/Tcl, the internal Tcl procedure names contain the object
64
- ID of the procedures pg_proc row as part of their name. Thus, different
79
+ ID of the procedure's pg_proc row as part of their name. Thus, different
65
80
argtype versions of the same <productname>Postgres</productname>
66
81
function are different for Tcl too.
67
82
</para>
@@ -72,17 +87,18 @@ $Header: /cvsroot/pgsql/doc/src/sgml/pltcl.sgml,v 2.6 2000/09/29 20:21:34 petere
72
87
<title>Defining Functions in PL/Tcl</title>
73
88
74
89
<para>
75
- To create a function in the PL/Tcl language, use the known syntax
90
+ To create a function in the PL/Tcl language, use the standard syntax
76
91
77
92
<programlisting>
78
- CREATE FUNCTION <replaceable>funcname</replaceable> <replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS '
93
+ CREATE FUNCTION <replaceable>funcname</replaceable> ( <replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS '
79
94
# PL/Tcl function body
80
95
' LANGUAGE 'pltcl';
81
96
</programlisting>
82
97
83
- When calling this function in a query, the arguments are given as
84
- variables $1 ... $n to the Tcl procedure body. So a little max function
85
- returning the higher of two int4 values would be created as:
98
+ When the function is called, the arguments are given as
99
+ variables $1 ... $n to the Tcl procedure body. For example,
100
+ a function
101
+ returning the higher of two int4 values could be defined as:
86
102
87
103
<programlisting>
88
104
CREATE FUNCTION tcl_max (int4, int4) RETURNS int4 AS '
@@ -120,13 +136,18 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
120
136
<para>
121
137
Sometimes (especially when using the SPI functions described later) it
122
138
is useful to have some global status data that is held between two
123
- calls to a procedure.
124
- All PL/Tcl procedures executed in one backend share the same
139
+ calls to a procedure. This is easily done since
140
+ all PL/Tcl procedures executed in one backend share the same
125
141
safe Tcl interpreter.
126
- To help protecting PL/Tcl procedures from side effects,
142
+ </para>
143
+ <para>
144
+ To help protect PL/Tcl procedures from unwanted side effects,
127
145
an array is made available to each procedure via the upvar
128
- command. The global name of this variable is the procedures internal
129
- name and the local name is GD.
146
+ command. The global name of this variable is the procedure's internal
147
+ name and the local name is GD. It is recommended that GD be used
148
+ for private status data of a procedure. Use regular Tcl global variables
149
+ only for values that you specifically intend to be shared among multiple
150
+ procedures.
130
151
</para>
131
152
</sect2>
132
153
@@ -140,7 +161,7 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
140
161
language.
141
162
</para>
142
163
<para>
143
- The informations from the trigger manager are given to the procedure body
164
+ The information from the trigger manager is given to the procedure body
144
165
in the following variables:
145
166
146
167
<variablelist>
@@ -259,8 +280,8 @@ CREATE FUNCTION overpaid_2 (EMP) RETURNS bool AS '
259
280
</para>
260
281
<para>
261
282
Here's a little example trigger procedure that forces an integer value
262
- in a table to keep track of the # of updates that are performed on the
263
- row. For new row's inserted, the value is initialized to 0 and then
283
+ in a table to keep track of the number of updates that are performed on the
284
+ row. For new rows inserted, the value is initialized to 0 and then
264
285
incremented on every update operation:
265
286
266
287
<programlisting>
@@ -305,7 +326,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
305
326
<para>
306
327
Fire a log message. Possible levels are NOTICE, ERROR,
307
328
FATAL, DEBUG and NOIND
308
- like for the <function>elog</function> C function.
329
+ as for the <function>elog</function> C function.
309
330
</para>
310
331
</listitem>
311
332
</varlistentry>
@@ -332,7 +353,7 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
332
353
"SELECT 'doesn't' AS ret"
333
354
</programlisting>
334
355
335
- what would cause a parse error during
356
+ which would cause a parse error during
336
357
<function>spi_exec</function> or
337
358
<function>spi_prepare</function>.
338
359
It should contain
0 commit comments