44.1. Overview

|  44.1. Overview  |                |                                            |                  |                             |
|:----------------:|----------------|--------------------------------------------|------------------|-----------------------------|
|[Prev](pltcl.html)|[Up](pltcl.html)|Chapter 44. PL/Tcl — Tcl Procedural Language|[Home](index.html)| [Next](pltcl-functions.html)|

---

## 44.1. Overview

 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.

 One compelling *good* 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 `elog()`. PL/Tcl provides no way to access internals of the database server or to gain OS-level access under the permissions of the PostgreSQL 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.

 The other notable implementation restriction is that Tcl functions cannot be used to create input/output functions for new data types.

 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 PL/Tcl called `PL/TclU` (for untrusted Tcl). This is exactly the same language except that a full Tcl interpreter is used. *If PL/TclU is used, it must be installed as an untrusted procedural language* so that only database superusers can create functions in it. The writer of a PL/TclU function must take care that the function cannot be used to do anything unwanted, since it will be able to do anything that could be done by a user logged in as the database administrator.

 The shared object code for the PL/Tcl and PL/TclU call handlers is automatically built and installed in the PostgreSQL library directory if Tcl support is specified in the configuration step of the installation procedure. To install PL/Tcl and/or PL/TclU in a particular database, use the `CREATE EXTENSION` command, for example `CREATE EXTENSION pltcl` or `CREATE EXTENSION pltclu`.

---

|             [Prev](pltcl.html)             | [Up](pltcl.html) |     [Next](pltcl-functions.html)    |
|:-------------------------------------------|:----------------:|------------------------------------:|
|Chapter 44. PL/Tcl — Tcl Procedural Language|[Home](index.html)| 44.2. PL/Tcl Functions and Arguments|

 // \<![CDATA[ \<-- For SVG support if ('WebSocket' in window) { (function() { function refreshCSS() { var sheets = [].slice.call(document.getElementsByTagName("link")); var head = document.getElementsByTagName("head")[0]; for (var i = 0; i \< sheets.length; ++i) { var elem = sheets[i]; head.removeChild(elem); var rel = elem.rel; if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") { var url = elem.href.replace(/(&|\\?)\_cacheOverride=\\d+/, ''); elem.href = url + (url.indexOf('?') \>= 0 ? '&' : '?') + '\_cacheOverride=' + (new Date().valueOf()); } head.appendChild(elem); } } var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://'; var address = protocol + window.location.host + window.location.pathname + '/ws'; var socket = new WebSocket(address); socket.onmessage = function(msg) { if (msg.data == 'reload') window.location.reload(); else if (msg.data == 'refreshcss') refreshCSS(); }; console.log('Live reload enabled.'); })(); } // ]]\>