PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

42.4. PL/Tcl 中的全局数据 #

有时,让一些全局数据在对同一个函数的两次调用之间保持,或者在 不同函数之间共享,是很有用的。 在 PL/Tcl 中这很容易做到,但有一些必须理解的限制。

出于安全原因,PL/Tcl 会为任何一个 SQL 角色执行的函数在一个该角色 专用的独立 Tcl 解释器中执行。 这防止了一个用户对另一个用户的 PL/Tcl 函数行为的意外或恶意 干扰。每个这样的解释器对任何“全局” Tcl 变量都会有 自己的取值。因此,两个 PL/Tcl 函数当且仅当由同一个 SQL 角色 执行时才会共享相同的全局变量。在单个会话在多个 SQL 角色下执行 代码(通过 SECURITY DEFINER 函数、使用 SET ROLE 等)的 应用中,您可能需要采取显式步骤来确保 PL/Tcl 函数能够共享数据。 要做到这一点,请确保需要相互通信的函数由同一个用户拥有,并把它们 标记为 SECURITY DEFINER。当然,您必须注意 这样的函数不能被用来做任何非预期的事情。

会话中使用的所有 PL/TclU 函数都在同一个 Tcl 解释器中执行,该解释器当然与用于 PL/Tcl 函数的解释器不同。 因此全局数据会在 PL/TclU 函数之间自动共享。 这不被视为安全风险,因为所有 PL/TclU 函数都在相同的信任级别 执行,即数据库超级用户的级别。

为了帮助保护 PL/Tcl 函数彼此免受意外干扰,每个函数都可以通过 upvar 命令使用一个全局 数组。这个变量的全局名是该函数的内部名称,局部名则是 GD。建议 把 GD 用于 函数的持久私有数据。只有专门打算在多个函数之间共享的值才使用 普通 Tcl 全局变量。(注意 GD 数组只在特定解释器内是全局的,因此它们 不能绕过上面提到的安全限制。)

使用 GD 的示例见下文的 spi_execp 例子。