40.4. PL/Tclにおけるグローバルデータ

ある関数の複数の呼び出し間で保持される、もしくは、異なる関数間で共有されるような、いくつかのグローバルデータを持つことが有意な場合があります。 これはPL/Tclで簡単に実現できますが、理解する必要がある制限がいくつかあります。

セキュリティ上の理由のため、PL/Tclは、任意のSQLロールによって呼び出された関数をそのロール用の別のTclインタプリタで実行します。 これにより、他のユーザのPL/Tcl関数の処理によってあるユーザへの事故または悪意の干渉を防止します。 こうしたインタプリタはそれぞれ任意の"グローバル"なTcl変数を持ちます。 したがって、同じSQLロールにより実行されていれば、2つのPL/Tcl関数は同じグローバル変数を共有します。 単一セッション内で(SECURITY DEFINER関数またはSET ROLEなどを通して)複数のSQLロールでコードを実行するアプリケーションでは、PL/Tcl関数が確実にデータを共有できるように明示的な処理を行う必要があるかもしれません。 このためには、通信しなければならない関数が同一ユーザで所有されていること、および、それがSECURITY DEFINERとして印がついていることを確実にしてください。 当然ながら、こうした関数が意図しない動作を行うために使用できないことに注意しなければなりません。

セッション内で使用されるすべてのPL/TclU関数は、当然ながらPL/Tcl関数とは別のインタプリタですが、同一のTclインタプリタ内で実行されます。 このためPL/TclU関数間ではグローバルデータは自動的に共有されます。 すべてのPL/TclU関数は同じ信頼レベル、すなわちデータベーススーパーユーザで実行されますので、これはセキュリティ上危険とはみなされません。

PL/Tcl関数が予期しない相互作用に巻き込まれないようにするために、upvarコマンドを使用することによって、各関数でアクセスできるグローバルな配列を作成することができます。 この変数のグローバル名は関数の内部名で、ローカル名はGDとなります。 関数の永続局所データではGDを使用することを推奨します。 複数の関数で共用させる予定の値に対してのみ、通常のTclのグローバル変数を使用してください。 (GD配列が特定のインタプリタ内のみでグローバルであることに注意してください。 このため、これらは上記のセキュリティ制限を迂回することはありません。)

後述のspi_execpの例の中にGDの使用例があります。