Postgresql 中文操作指南
44.4. Global Data in PL/Tcl #
有时,在两次调用函数之间保留一些全局数据或在不同函数之间共享一些全局数据是非常有用的。这在 PL/Tcl 中很容易做到,但也有一些必须了解的限制。
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 in PL/Tcl, but there are some restrictions that must be understood.
出于安全原因,PL/Tcl 执行由任何一个 SQL 角色调用的函数时,会针对该角色使用一个单独的 Tcl 解释器。这可以防止某个用户意外或恶意地干扰另一个用户的 PL/Tcl 函数的行为。每个这样的解释器都将对任何“全局”Tcl 变量都有自己的值。因此,当且仅当两个 PL/Tcl 函数由同一个 SQL 角色执行时,这两个函数才会共享相同的全局变量。在一个会话中,一个会话在多个 SQL 角色下执行代码(通过 SECURITY DEFINER 函数使用 SET ROLE 等)时,您可能需要采取明确的步骤来确保 PL/Tcl 函数可以共享数据。要做到这一点,请确保应该通信的函数由同一个用户拥有,并将其标记为 SECURITY DEFINER。您当然必须小心,此类函数不会被用来做任何意外的事情。
For security reasons, PL/Tcl executes functions called by any one SQL role in a separate Tcl interpreter for that role. This prevents accidental or malicious interference by one user with the behavior of another user’s PL/Tcl functions. Each such interpreter will have its own values for any “global” Tcl variables. Thus, two PL/Tcl functions will share the same global variables if and only if they are executed by the same SQL role. In an application wherein a single session executes code under multiple SQL roles (via SECURITY DEFINER functions, use of SET ROLE, etc.) you may need to take explicit steps to ensure that PL/Tcl functions can share data. To do that, make sure that functions that should communicate are owned by the same user, and mark them SECURITY DEFINER. You must of course take care that such functions can’t be used to do anything unintended.
在会话中使用的所有 PL/TclU 函数都在同一个 Tcl 解释器中执行,该解释器与用于 PL/Tcl 函数的解释器不同。因此,全局数据会在 PL/TclU 函数之间自动共享。这并不被认为是一个安全风险,因为所有 PL/TclU 函数都在相同的信任级别下执行,即数据库超级用户的信任级别。
All PL/TclU functions used in a session execute in the same Tcl interpreter, which of course is distinct from the interpreter(s) used for PL/Tcl functions. So global data is automatically shared between PL/TclU functions. This is not considered a security risk because all PL/TclU functions execute at the same trust level, namely that of a database superuser.
为了保护 PL/Tcl 函数不会意外干扰互相之间的执行,一个全局数组可以通过 upvar 指令向每个函数提供。此变量的全局名称是函数的内部名称,而本地名称是 GD。建议将 GD 用于函数的持久型专用数据。仅使用常规 Tcl 全局变量来存取特定想要在多个函数中共享的值。(注意,GD 数组仅是特定解释器内部的全局变量,因此它们不会绕过上述安全限制。)
To help protect PL/Tcl functions from unintentionally interfering with each other, a global array is made available to each function via the upvar command. The global name of this variable is the function’s internal name, and the local name is GD. It is recommended that 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. (Note that the GD arrays are only global within a particular interpreter, so they do not bypass the security restrictions mentioned above.)
GD 使用示例描述见下面的 spi_execp 示例。
An example of using GD appears in the spi_execp example below.