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で簡単に実現できますが、理解する必要がある制限がいくつかあります。
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 <quote>global</quote> 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 <literal>SECURITY
DEFINER</literal> functions, use of <command>SET ROLE</command>, 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 <literal>SECURITY DEFINER</literal>. You must of
course take care that such functions can't be used to do anything
unintended.
セキュリティ上の理由のため、PL/Tclは、任意のSQLロールによって呼び出された関数をそのロール用の別のTclインタプリタで実行します。
これにより、あるユーザの事故または悪意によって他のユーザのPL/Tcl関数の動作が干渉されてしまうことを防ぎます。
こうしたインタプリタはそれぞれ独自の「グローバル」なTcl変数を持ちます。
したがって、同じSQLロールにより実行されていれば、2つのPL/Tcl関数は同じグローバル変数を共有します。
単一セッション内で(SECURITY DEFINER
関数またはSET ROLE
などを通して)複数のSQLロールでコードを実行するアプリケーションでは、PL/Tcl関数が確実にデータを共有できるように明示的な処理を行う必要があるかもしれません。
このためには、通信しなければならない関数が同一ユーザで所有されていること、および、それがSECURITY DEFINER
として印がついていることを確実にしてください。
当然ながら、こうした関数が意図しない動作を行うために使われることのないよう注意しなければなりません。
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/TclU関数は、当然ながらPL/Tcl関数とは別のインタプリタですが、同一のTclインタプリタ内で実行されます。 このためPL/TclU関数間ではグローバルデータは自動的に共有されます。 すべてのPL/TclU関数は同じ信頼レベル、すなわちデータベーススーパーユーザで実行されますので、これはセキュリティ上危険とはみなされません。
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</function>
command. The global name of this variable is the function's internal
name, and the local name is <literal>GD</literal>. It is recommended that
<literal>GD</literal> 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 <literal>GD</literal> arrays are only
global within a particular interpreter, so they do not bypass the
security restrictions mentioned above.)
PL/Tcl関数が予期しない相互作用に巻き込まれないようにするために、upvar
コマンドを使用することによって、各関数でアクセスできるグローバルな配列を作成することができます。
この変数のグローバル名は関数の内部名で、ローカル名はGD
となります。
関数の永続局所データではGD
を使用することを推奨します。
複数の関数で共用させる予定の値に対してのみ、通常のTclのグローバル変数を使用してください。
(GD
配列が特定のインタプリタ内のみでグローバルであることに注意してください。
このため、これらは上記のセキュリティ制限を迂回することはありません。)
An example of using <literal>GD</literal> appears in the
<function>spi_execp</function> example below.
後述のspi_execp
の例の中にGD
の使用例があります。