A useful extension to <productname>PostgreSQL</productname> typically includes
multiple SQL objects; for example, a new data type will require new
functions, new operators, and probably new index operator classes.
It is helpful to collect all these objects into a single package
to simplify database management. <productname>PostgreSQL</productname> calls
such a package an <firstterm>extension</firstterm>. To define an extension,
you need at least a <firstterm>script file</firstterm> that contains the
<acronym>SQL</acronym> commands to create the extension's objects, and a
<firstterm>control file</firstterm> that specifies a few basic properties
of the extension itself. If the extension includes C code, there
will typically also be a shared library file into which the C code
has been built. Once you have these files, a simple
<link linkend="sql-createextension"><command>CREATE EXTENSION</command></link> command loads the objects into
your database.
PostgreSQLへの有用な拡張は通常、複数のSQLオブジェクトを含んでいます。
例えば、新しいデータ型は新しい関数、新しい演算子、おそらく新しいインデックス演算子クラスを必要とします。
これらのオブジェクトをすべて単一のパッケージとしてまとめることは、データベース管理を単純化するために役に立ちます。
PostgreSQLではこうしたパッケージを拡張とよびます。
拡張を定義するためには、少なくとも、拡張のオブジェクトを作成するためのSQLコマンドを含むスクリプトファイル、拡張自身の数個の基本属性を指定する制御ファイルが必要です。
また拡張がCコードを含む場合、通常Cコードで構築された共有ライブラリが存在します。
これらのファイルがあれば、単純なCREATE EXTENSION
コマンドがそのオブジェクトをデータベース内に読み込みます。
The main advantage of using an extension, rather than just running the
<acronym>SQL</acronym> script to load a bunch of <quote>loose</quote> objects
into your database, is that <productname>PostgreSQL</productname> will then
understand that the objects of the extension go together. You can
drop all the objects with a single <link linkend="sql-dropextension"><command>DROP EXTENSION</command></link>
command (no need to maintain a separate <quote>uninstall</quote> script).
Even more useful, <application>pg_dump</application> knows that it should not
dump the individual member objects of the extension — it will
just include a <command>CREATE EXTENSION</command> command in dumps, instead.
This vastly simplifies migration to a new version of the extension
that might contain more or different objects than the old version.
Note however that you must have the extension's control, script, and
other files available when loading such a dump into a new database.
拡張を使用する主な利点は、SQLスクリプトを実行するだけでデータベースに「粗な」なオブジェクトの群をロードできることではなく、PostgreSQLが拡張のオブジェクトをまとまったものと理解できることです。
単一のDROP EXTENSION
コマンドでオブジェクトすべてを削除できます(個々の「アンインストール」スクリプトを保守する必要はありません)。
もっと有用なことは、pg_dumpが拡張の個々のメンバオブジェクトをダンプしてはならないことを把握していることです。
代わりにダンプ内にはCREATE EXTENSION
コマンドだけが含まれます。
これは、古いバージョンよりも多くのまたは異なるオブジェクトを含む可能性がある、拡張の新しいバージョンへの移行を大きく単純化します。
しかし、こうしたダンプを新しいデータベースにロードする際には、拡張の制御ファイル、スクリプトファイル、その他のファイルが利用できるようにしておく必要があります。
<productname>PostgreSQL</productname> will not let you drop an individual object
contained in an extension, except by dropping the whole extension.
Also, while you can change the definition of an extension member object
(for example, via <command>CREATE OR REPLACE FUNCTION</command> for a
function), bear in mind that the modified definition will not be dumped
by <application>pg_dump</application>. Such a change is usually only sensible if
you concurrently make the same change in the extension's script file.
(But there are special provisions for tables containing configuration
data; see <xref linkend="extend-extensions-config-tables"/>.)
In production situations, it's generally better to create an extension
update script to perform changes to extension member objects.
PostgreSQLはユーザに、拡張全体を削除させる以外に、拡張内に含まれる個々のオブジェクトを削除させません。
また、拡張のメンバオブジェクトの定義を変更する(例えば関数ではCREATE OR REPLACE FUNCTION
を介して変更する)ことはできますが、変更した定義はpg_dumpによりダンプされないことに留意してください。
こうした変更は通常、同時に拡張のスクリプトファイルにも同じ変更を行った場合のみ認識できます。
(しかし設定データを持つテーブルに対しては特殊な準備があります。36.17.3を参照してください。)
本番環境では、拡張メンバオブジェクトへの変更を処理するために拡張更新スクリプトを作成するのが一般により良い方法です。
The extension script may set privileges on objects that are part of the
extension, using <command>GRANT</command> and <command>REVOKE</command>
statements. The final set of privileges for each object (if any are set)
will be stored in the
<link linkend="catalog-pg-init-privs"><structname>pg_init_privs</structname></link>
system catalog. When <application>pg_dump</application> is used, the
<command>CREATE EXTENSION</command> command will be included in the dump, followed
by the set of <command>GRANT</command> and <command>REVOKE</command>
statements necessary to set the privileges on the objects to what they were
at the time the dump was taken.
拡張スクリプトは、GRANT
文とREVOKE
文を使って拡張の一部のオブジェクトに権限を設定するかもしれません。
それぞれのオブジェクト(どれかが設定される場合)の最終的な権限のセットは、pg_init_privs
システムカタログに格納されます。
pg_dumpが使用されると、CREATE EXTENSION
コマンドがダンプ内に含まれ、オブジェクトの権限をダンプが取られた時点のものに設定するために必要となるGRANT
文とREVOKE
文が後に続きます。
<productname>PostgreSQL</productname> does not currently support extension scripts
issuing <command>CREATE POLICY</command> or <command>SECURITY LABEL</command>
statements. These are expected to be set after the extension has been
created. All RLS policies and security labels on extension objects will be
included in dumps created by <application>pg_dump</application>.
PostgreSQLは、現在拡張スクリプトにてCREATE POLICY
文やSECURITY LABEL
文の発行をサポートしていません。
これらは拡張が作成された後に設定されるべきです。
拡張オブジェクトのすべての行セキュリティポリシーとセキュリティラベルはpg_dumpによって作成されたダンプに含まれます。
The extension mechanism also has provisions for packaging modification
scripts that adjust the definitions of the SQL objects contained in an
extension. For example, if version 1.1 of an extension adds one function
and changes the body of another function compared to 1.0, the extension
author can provide an <firstterm>update script</firstterm> that makes just those
two changes. The <command>ALTER EXTENSION UPDATE</command> command can then
be used to apply these changes and track which version of the extension
is actually installed in a given database.
また拡張機構は、拡張に含まれるSQLオブジェクトの定義を調整するパッケージ調整スクリプトを準備しています。
例えば、拡張のバージョン1.1でバージョン1.0と比べて1つの関数を追加し、他の関数本体を変更する場合、拡張の作成者はこれらの2つの変更のみを行う更新スクリプトを提供できます。
そしてALTER EXTENSION UPDATE
コマンドを使用して、これらの変更を適用し、指定されたデータベース内に実際にインストールされた拡張のバージョンが何かを記録します。
The kinds of SQL objects that can be members of an extension are shown in
the description of <link linkend="sql-alterextension"><command>ALTER EXTENSION</command></link>. Notably, objects
that are database-cluster-wide, such as databases, roles, and tablespaces,
cannot be extension members since an extension is only known within one
database. (Although an extension script is not prohibited from creating
such objects, if it does so they will not be tracked as part of the
extension.) Also notice that while a table can be a member of an
extension, its subsidiary objects such as indexes are not directly
considered members of the extension.
Another important point is that schemas can belong to extensions, but not
vice versa: an extension as such has an unqualified name and does not
exist <quote>within</quote> any schema. The extension's member objects,
however, will belong to schemas whenever appropriate for their object
types. It may or may not be appropriate for an extension to own the
schema(s) its member objects are within.
拡張のメンバとなり得るSQLオブジェクトの種類をALTER EXTENSION
で説明します。
拡張は1つのデータベースの中でのみ認識されますので、データベース、ロール、テーブル空間などデータベースクラスタ全体のオブジェクトは拡張のメンバにすることができないことに注意してください。
(拡張のスクリプトでこうしたオブジェクトを生成することは禁止されていませんが、作成したとしても、拡張の一部として記録されません。)
また、テーブルは拡張のメンバになることができますが、インデックスなどそれに付随するオブジェクトは拡張の直接的なメンバとはみなされません。
もう一つの重要な点は、スキーマは拡張に属すことがありますがその逆はないということです。
拡張は非修飾名でいかなるスキーマ「の中に」も存在しません。
しかし、拡張のメンバオブジェクトはオブジェクトの型が適切であればスキーマに属します。
拡張が自身のメンバオブジェクトが属するスキーマを所有することは適切かも知れませんし、そうでないかも知れません。
If an extension's script creates any temporary objects (such as temp tables), those objects are treated as extension members for the remainder of the current session, but are automatically dropped at session end, as any temporary object would be. This is an exception to the rule that extension member objects cannot be dropped without dropping the whole extension. ある拡張のスクリプトが(一時テーブルのような)一時オブジェクトを作成する場合、現在のセッションで、以降そのオブジェクトは拡張のメンバとして扱われます。 しかしすべての一時オブジェクト同様、セッションの終わりに削除されます。 これは、拡張全体を削除することなしに、拡張のメンバオブジェクトは削除できない、という規則の例外です。
The <command>CREATE EXTENSION</command> command relies on a control
file for each extension, which must be named the same as the extension
with a suffix of <literal>.control</literal>, and must be placed in the
installation's <literal>SHAREDIR/extension</literal> directory. There
must also be at least one <acronym>SQL</acronym> script file, which follows the
naming pattern
<literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.sql</literal>
(for example, <literal>foo--1.0.sql</literal> for version <literal>1.0</literal> of
extension <literal>foo</literal>). By default, the script file(s) are also
placed in the <literal>SHAREDIR/extension</literal> directory; but the
control file can specify a different directory for the script file(s).
CREATE EXTENSION
コマンドは各拡張に関して、拡張と同じ名前に.control
という拡張子を持つファイル名である必要がある、制御ファイルに依存します。
また、このファイルはインストレーションのSHAREDIR/extension
ディレクトリ内に存在しなければなりません。
また少なくとも1つの、
という命名規約(例えばextension
--version
.sqlfoo
拡張のバージョン1.0
ではfoo--1.0.sql
)に従ったSQLスクリプトファイルが存在しなければなりません。
デフォルトでは、このスクリプトファイルもSHAREDIR/extension
ディレクトリに格納されますが、制御ファイルでスクリプトファイルを別のディレクトリに指定できます。
The file format for an extension control file is the same as for the
<filename>postgresql.conf</filename> file, namely a list of
<replaceable>parameter_name</replaceable> <literal>=</literal> <replaceable>value</replaceable>
assignments, one per line. Blank lines and comments introduced by
<literal>#</literal> are allowed. Be sure to quote any value that is not
a single word or number.
拡張の制御ファイルのファイル書式はpostgresql.conf
ファイルと同じです。
すなわち、parameter_name
=
value
という代入を1行当たり1つ記述します。
空行および#
から始まるコメントが許されます。
単一の単語または数字ではない値にはすべて引用符で確実にくくってください。
A control file can set the following parameters: 制御ファイルは以下のパラメータを設定できます。
directory
(string
) #
The directory containing the extension's <acronym>SQL</acronym> script
file(s). Unless an absolute path is given, the name is relative to
the installation's <literal>SHAREDIR</literal> directory. The
default behavior is equivalent to specifying
<literal>directory = 'extension'</literal>.
拡張のSQLスクリプトファイルを含むディレクトリです。
絶対パスで指定されていない限り、この名前はインストレーションのSHAREDIR
ディレクトリからの相対パスになります。
デフォルトの動作はdirectory = 'extension'
と指定した場合と同じです。
default_version
(string
) #
The default version of the extension (the one that will be installed
if no version is specified in <command>CREATE EXTENSION</command>). Although
this can be omitted, that will result in <command>CREATE EXTENSION</command>
failing if no <literal>VERSION</literal> option appears, so you generally
don't want to do that.
拡張のデフォルトのバージョン(CREATE EXTENSION
でバージョン指定がない場合にインストールされるバージョン)です。
これは省略できますが、その場合VERSION
オプションがないCREATE EXTENSION
は失敗します。
ですので通常省略しようとは思わないでしょう。
comment
(string
) #A comment (any string) about the extension. The comment is applied when initially creating an extension, but not during extension updates (since that might override user-added comments). Alternatively, the extension's comment can be set by writing a <xref linkend="sql-comment"/> command in the script file. 拡張に関するコメント(任意の文字列)です。 最初に拡張が作成されるときにコメントは適用されますが、拡張が更新される間はされません(ユーザが追加したコメントを上書いてしまうため)。 この他の方法として、スクリプトファイル内でCOMMENTコマンドを使用してコメントを設定できます。
encoding
(string
) #The character set encoding used by the script file(s). This should be specified if the script files contain any non-ASCII characters. Otherwise the files will be assumed to be in the database encoding. スクリプトファイルで使用される文字セット符号化方式です。 スクリプトファイルに何らかの非ASCII文字が含まれる場合に指定しなければなりません。 指定がなければ、ファイルはデータベース符号化方式であると仮定されます。
module_pathname
(string
) #
The value of this parameter will be substituted for each occurrence
of <literal>MODULE_PATHNAME</literal> in the script file(s). If it is not
set, no substitution is made. Typically, this is set to
<literal>$libdir/<replaceable>shared_library_name</replaceable></literal> and
then <literal>MODULE_PATHNAME</literal> is used in <command>CREATE
FUNCTION</command> commands for C-language functions, so that the script
files do not need to hard-wire the name of the shared library.
このパラメータの値でスクリプトファイル内のMODULE_PATHNAME
の出現箇所が置換されます。
設定されていない場合は置換は行われません。
通常これは、スクリプトファイル内で共有ライブラリの名前を直接書き込む必要がなくなるように$libdir/
に設定され、C言語関数ではshared_library_name
CREATE FUNCTION
コマンド中でMODULE_PATHNAME
を使用します。
requires
(string
) #
A list of names of extensions that this extension depends on,
for example <literal>requires = 'foo, bar'</literal>. Those
extensions must be installed before this one can be installed.
拡張が依存する拡張の名前のリストです。
例えばrequires = 'foo, bar'
です。
対象の拡張がインストールできるようになる前に、これらの拡張がインストールされていなければなりません。
no_relocate
(string
) #
A list of names of extensions that this extension depends on that
should be barred from changing their schemas via <command>ALTER
EXTENSION ... SET SCHEMA</command>.
This is needed if this extension's script references the name
of a required extension's schema (using
the <literal>@extschema:<replaceable>name</replaceable>@</literal>
syntax) in a way that cannot track renames.
この拡張が依存していて、ALTER EXTENSION ... SET SCHEMA
でスキーマを変更することを禁止される拡張の名前の一覧です。
この拡張のスクリプトが、(@extschema:
構文を使って)必要な拡張のスキーマの名前を参照し、名前変更を追跡できない場合に必要です。
name
@
superuser
(boolean
) #
If this parameter is <literal>true</literal> (which is the default),
only superusers can create the extension or update it to a new
version (but see also <varname>trusted</varname>, below).
If it is set to <literal>false</literal>, just the privileges
required to execute the commands in the installation or update script
are required.
This should normally be set to <literal>true</literal> if any of the
script commands require superuser privileges. (Such commands would
fail anyway, but it's more user-friendly to give the error up front.)
このパラメータがtrue
(デフォルト)の場合、スーパーユーザのみが拡張を作成または新しいバージョンに更新できます(ただし、後述するtrusted
も参照してください)。
false
に設定されている場合は、インストール中のコマンド実行またはスクリプト更新のために必要な権限のみが必要とされます。
いずれかスクリプトコマンドがスーパーユーザ権限を必要とするなら、通常はtrue
に設定されるべきです。
(このようなコマンドはいずれにせよ失敗するでしょうけれども、前もってエラーを出す方がよりユーザフレンドリです。)
trusted
(boolean
) #
This parameter, if set to <literal>true</literal> (which is not the
default), allows some non-superusers to install an extension that
has <varname>superuser</varname> set to <literal>true</literal>.
Specifically, installation will be permitted for anyone who has
<literal>CREATE</literal> privilege on the current database.
When the user executing <command>CREATE EXTENSION</command> is not
a superuser but is allowed to install by virtue of this parameter,
then the installation or update script is run as the bootstrap
superuser, not as the calling user.
This parameter is irrelevant if <varname>superuser</varname> is
<literal>false</literal>.
Generally, this should not be set true for extensions that could
allow access to otherwise-superuser-only abilities, such as
file system access.
Also, marking an extension trusted requires significant extra effort
to write the extension's installation and update script(s) securely;
see <xref linkend="extend-extensions-security"/>.
このパラメータは、true
(デフォルトではありません)に設定されている場合、一部の非スーパーユーザがsuperuser
にtrue
を設定している拡張をインストールできるようにします。
具体的には、現在のデータベースにCREATE
権限を持っているユーザにインストールが許可されるようになります。
CREATE EXTENSION
を実行するユーザがスーパーユーザでないけれども本パラメータの効力でインストールできるとき、インストールやスクリプトの更新は実行したユーザではなく、サービス起動のスーパーユーザとして実行されます。
superuser
がfalse
の場合、本パラメータは無意味です。
一般に、ファイルシステムのアクセスなど、別の方法ではスーパーユーザのみができることにアクセスができる拡張に対して、これをtrueにすべきではありません。
また、拡張をtrustedとして作成するには、拡張のインストールとスクリプト更新を安全に記述するために、かなりの追加の労力が影響が必要です。36.17.6を参照してください。
relocatable
(boolean
) #
An extension is <firstterm>relocatable</firstterm> if it is possible to move
its contained objects into a different schema after initial creation
of the extension. The default is <literal>false</literal>, i.e., the
extension is not relocatable.
See <xref linkend="extend-extensions-relocation"/> for more information.
拡張を最初に作成した後に拡張により含まれるオブジェクトを別のスキーマに移動できる場合、拡張は再配置可能です。
デフォルトはfalse
、つまり、拡張は再配置可能ではありません。
詳しくは36.17.2を参照してください。
schema
(string
) #
This parameter can only be set for non-relocatable extensions.
It forces the extension to be loaded into exactly the named schema
and not any other.
The <varname>schema</varname> parameter is consulted only when
initially creating an extension, not during extension updates.
See <xref linkend="extend-extensions-relocation"/> for more information.
このパラメータは再配置可能ではない拡張に対してのみ設定できます。
拡張が指名したスキーマのみにロードされ、他にはロードされないことを強制します。
schema
パラメータは、拡張を最初に作成するときにのみ参照され、拡張が更新される間はされません。
詳しくは36.17.2を参照してください。
In addition to the primary control file
<literal><replaceable>extension</replaceable>.control</literal>,
an extension can have secondary control files named in the style
<literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.control</literal>.
If supplied, these must be located in the script file directory.
Secondary control files follow the same format as the primary control
file. Any parameters set in a secondary control file override the
primary control file when installing or updating to that version of
the extension. However, the parameters <varname>directory</varname> and
<varname>default_version</varname> cannot be set in a secondary control file.
主制御ファイル
に加え、拡張はextension
.control
という形の名前の副制御ファイルを持つことができます。
これらを提供する場合は、スクリプトファイルディレクトリに格納しなければなりません。
副制御ファイルは主制御ファイルと同じ書式に従います。
拡張の対応するバージョンをインストールまたは更新する時、副制御ファイル内で設定されるパラメータはいずれも、主制御ファイルを上書きします。
しかしextension
--version
.controldirectory
およびdefault_version
パラメータは副制御ファイルで設定することはできません。
An extension's <acronym>SQL</acronym> script files can contain any SQL commands,
except for transaction control commands (<command>BEGIN</command>,
<command>COMMIT</command>, etc.) and commands that cannot be executed inside a
transaction block (such as <command>VACUUM</command>). This is because the
script files are implicitly executed within a transaction block.
拡張のSQLスクリプトファイルにはトランザクション制御コマンド(BEGIN
、COMMIT
など)およびトランザクションブロックの内側で実行できないコマンド(VACUUM
など)を除く任意のSQLコマンドを含めることができます。
スクリプトファイルが暗黙的にトランザクションブロック内で実行されるためです。
An extension's <acronym>SQL</acronym> script files can also contain lines
beginning with <literal>\echo</literal>, which will be ignored (treated as
comments) by the extension mechanism. This provision is commonly used
to throw an error if the script file is fed to <application>psql</application>
rather than being loaded via <command>CREATE EXTENSION</command> (see example
script in <xref linkend="extend-extensions-example"/>).
Without that, users might accidentally load the
extension's contents as <quote>loose</quote> objects rather than as an
extension, a state of affairs that's a bit tedious to recover from.
拡張のSQLスクリプトファイルには、\echo
から始まる行を含めることができます。
この行は拡張の機構では無視されます(コメントとして扱われます)。
これは、このスクリプトがCREATE EXTENSION
(36.17.7のスクリプト例を参照)ではなくpsqlに渡された場合にエラーを発生するために一般的に使用するために用意されたものです。
これがないと、ユーザは間違って拡張としてではなく、「まとまっていない」オブジェクトとして拡張の内容をロードしてしまい、復旧が多少困難な状態になる可能性があります。
If the extension script contains the
string <literal>@extowner@</literal>, that string is replaced with the
(suitably quoted) name of the user calling <command>CREATE
EXTENSION</command> or <command>ALTER EXTENSION</command>. Typically
this feature is used by extensions that are marked trusted to assign
ownership of selected objects to the calling user rather than the
bootstrap superuser. (One should be careful about doing so, however.
For example, assigning ownership of a C-language function to a
non-superuser would create a privilege escalation path for that user.)
拡張のスクリプトに文字列@extowner@
が含まれている場合、この文字列は、CREATE EXTENSION
やALTER EXTENSION
を実行した(適切にクォートされた)ユーザ名で置き換えられます。
典型的には、この機能はtrustedと印付けされた拡張が選択されたオブジェクトにサービス起動のスーパーユーザではなく実行したユーザを所有者として割り当てる際に使われます。
(とはいえ、このようにするには注意深くすべきです。例えば、C言語関数の所有者を非スーパーユーザに割り当てると、そのユーザに権限昇格の経路を作ることになるでしょう)
While the script files can contain any characters allowed by the specified
encoding, control files should contain only plain ASCII, because there
is no way for <productname>PostgreSQL</productname> to know what encoding a
control file is in. In practice this is only an issue if you want to
use non-ASCII characters in the extension's comment. Recommended
practice in that case is to not use the control file <varname>comment</varname>
parameter, but instead use <command>COMMENT ON EXTENSION</command>
within a script file to set the comment.
スクリプトファイルは指定した符号化方式で認められる任意の文字を含めることができますが、PostgreSQLが制御ファイルの符号化方式が何かを把握する方法がありませんので、制御ファイルにはASCII文字のみを含めなければなりません。
実際には、拡張のコメントに非ASCII文字を含めたい場合にのみ、これが問題になります。
このような場合には、制御ファイルのcomment
を使用せず、代わりにコメントを設定するためにスクリプトファイル内でCOMMENT ON EXTENSION
を使用することを勧めます。
Users often wish to load the objects contained in an extension into a different schema than the extension's author had in mind. There are three supported levels of relocatability: ユーザは拡張に含まれるオブジェクトを拡張の作成者が考えていたスキーマとは別のスキーマにロードしたいとよく考えます。 再配置性に関して3つのレベルがサポートされます。
A fully relocatable extension can be moved into another schema
at any time, even after it's been loaded into a database.
This is done with the <command>ALTER EXTENSION SET SCHEMA</command>
command, which automatically renames all the member objects into
the new schema. Normally, this is only possible if the extension
contains no internal assumptions about what schema any of its
objects are in. Also, the extension's objects must all be in one
schema to begin with (ignoring objects that do not belong to any
schema, such as procedural languages). Mark a fully relocatable
extension by setting <literal>relocatable = true</literal> in its control
file.
完全な再配置可能な拡張は、いつでも、データベースにロードされた後であっても、他のスキーマに移動させることができます。
これは、自動的にすべてのメンバオブジェクトを新しいスキーマに名前を変更する、ALTER EXTENSION SET SCHEMA
を用いて行います。
通常これは、拡張がオブジェクトが含まれるスキーマが何かに関して内部的な仮定を持たない場合のみ可能です。
また、拡張のオブジェクト(手続き言語など何らかのスキーマに属さないオブジェクトは無視して)はすべて最初に1つのスキーマ内に存在しなければなりません。
制御ファイル内でrelocatable = true
と設定することで、完全な再配置可能と印付けます。
An extension might be relocatable during installation but not
afterwards. This is typically the case if the extension's script
file needs to reference the target schema explicitly, for example
in setting <literal>search_path</literal> properties for SQL functions.
For such an extension, set <literal>relocatable = false</literal> in its
control file, and use <literal>@extschema@</literal> to refer to the target
schema in the script file. All occurrences of this string will be
replaced by the actual target schema's name (double-quoted if
necessary) before the script is executed. The user can set the
target schema using the
<literal>SCHEMA</literal> option of <command>CREATE EXTENSION</command>.
拡張はインストール処理の間再配置可能ですが、その後再配置することはできません。
通常これは、拡張のスクリプトファイルが、SQL関数用のsearch_path
属性の設定など、対象のスキーマを明示的に参照する必要がある場合です。
こうした拡張では、制御ファイルでrelocatable = false
と設定し、スクリプトファイル内で対象のスキーマを参照するために@extschema@
を設定してください。
この文字列の出現箇所はすべて、スクリプトが実行される前に、(必要ならば二重引用符で括られて)実際の対象のスキーマ名に置換されます。
ユーザはCREATE EXTENSION
のSCHEMA
オプションを使用して対象のスキーマを設定できます。
If the extension does not support relocation at all, set
<literal>relocatable = false</literal> in its control file, and also set
<literal>schema</literal> to the name of the intended target schema. This
will prevent use of the <literal>SCHEMA</literal> option of <command>CREATE
EXTENSION</command>, unless it specifies the same schema named in the control
file. This choice is typically necessary if the extension contains
internal assumptions about its schema name that can't be replaced by
uses of <literal>@extschema@</literal>. The <literal>@extschema@</literal>
substitution mechanism is available in this case too, although it is
of limited use since the schema name is determined by the control file.
拡張が再配置をまったくサポートしない場合、制御ファイルでrelocatable = false
を設定し、かつ、schema
を意図している対象スキーマの名前に設定してください。
これは、制御ファイル内で指定されたスキーマと同じ名前が指定されていない限り、CREATE EXTENSION
のSCHEMA
オプションの指定を阻止します。
この選択は通常、拡張が@extschema@
を使用して置き換えることができないスキーマ名について内部的な仮定を持つ場合に必要です。
@extschema@
置換機構はこの場合でも使用できますが、スキーマ名が制御ファイルによって決定されますので、用途は限定されます。
In all cases, the script file will be executed with
<xref linkend="guc-search-path"/> initially set to point to the target
schema; that is, <command>CREATE EXTENSION</command> does the equivalent of
this:
すべての場合において、スクリプトファイルは対象のスキーマを指し示すようにあらかじめ設定したsearch_pathを用いて実行されます。
つまりCREATE EXTENSION
は以下と同じことを行います。
SET LOCAL search_path TO @extschema@, pg_temp;
This allows the objects created by the script file to go into the target
schema. The script file can change <varname>search_path</varname> if it wishes,
but that is generally undesirable. <varname>search_path</varname> is restored
to its previous setting upon completion of <command>CREATE EXTENSION</command>.
これによりスクリプトファイルで作成されるオブジェクトを対象のスキーマ内に格納できます。
スクリプトファイルは要望に応じてsearch_path
を変更できますが、一般的には望まれません。
CREATE EXTENSION
の実行後、search_path
は以前の設定に戻されます。
The target schema is determined by the <varname>schema</varname> parameter in
the control file if that is given, otherwise by the <literal>SCHEMA</literal>
option of <command>CREATE EXTENSION</command> if that is given, otherwise the
current default object creation schema (the first one in the caller's
<varname>search_path</varname>). When the control file <varname>schema</varname>
parameter is used, the target schema will be created if it doesn't
already exist, but in the other two cases it must already exist.
対象のスキーマは制御ファイル内のschema
パラメータがあればこのパラメータにより決定されます。
このパラメータがなければ、CREATE EXTENSION
のSCHEMA
があればこの値で決まり、これ以外の場合は現在のデフォルトのオブジェクト生成用スキーマ(呼び出し元のsearch_path
の最初のもの)になります。
制御ファイルのschema
パラメータが使用される時、対象のスキーマが存在しない場合は作成されますが、これ以外の2つの場合ではすでに存在しなければなりません。
If any prerequisite extensions are listed in <varname>requires</varname>
in the control file, their target schemas are added to the initial
setting of <varname>search_path</varname>, following the new
extension's target schema. This allows their objects to be visible to
the new extension's script file.
何らかの事前に必要な拡張が制御ファイル内のrequires
に列挙されていた場合、それらのターゲットスキーマは新しい機能拡張のターゲットスキーマに続いてsearch_path
の初期設定に追加されます。
これにより新しい拡張のスクリプトファイルからそれらのオブジェクトが可視になります。
For security, <literal>pg_temp</literal> is automatically appended to
the end of <varname>search_path</varname> in all cases.
安全のため、全てのケースにおいてpg_temp
は自動的にsearch_path
の最後に追記されます。
Although a non-relocatable extension can contain objects spread across
multiple schemas, it is usually desirable to place all the objects meant
for external use into a single schema, which is considered the extension's
target schema. Such an arrangement works conveniently with the default
setting of <varname>search_path</varname> during creation of dependent
extensions.
再配置不可能な拡張は複数スキーマにまたがるオブジェクトを含めることができますが、通常、外部使用を意図したオブジェクトはすべて単一スキーマに格納することが望まれます。
この単一スキーマが拡張の対象のスキーマとみなされます。
こうした調整は依存する拡張を作成する間、デフォルトのsearch_path
設定を都合に合わせて扱います。
If an extension references objects belonging to another extension,
it is recommended to schema-qualify those references. To do that,
write <literal>@extschema:<replaceable>name</replaceable>@</literal>
in the extension's script file, where <replaceable>name</replaceable>
is the name of the other extension (which must be listed in this
extension's <literal>requires</literal> list). This string will be
replaced by the name (double-quoted if necessary) of that extension's
target schema.
Although this notation avoids the need to make hard-wired assumptions
about schema names in the extension's script file, its use may embed
the other extension's schema name into the installed objects of this
extension. (Typically, that happens
when <literal>@extschema:<replaceable>name</replaceable>@</literal> is
used inside a string literal, such as a function body or
a <varname>search_path</varname> setting. In other cases, the object
reference is reduced to an OID during parsing and does not require
subsequent lookups.) If the other extension's schema name is so
embedded, you should prevent the other extension from being relocated
after yours is installed, by adding the name of the other extension to
this one's <literal>no_relocate</literal> list.
拡張が別の拡張に属するオブジェクトを参照する場合は、それらの参照をスキーマ修飾することをお勧めします。
これを行うには、拡張のスクリプトファイルに@extschema:
と記述します。ここで、name
@name
は他の拡張の名前です(他の拡張はこの拡張のrequires
リストに記載されていることが必要です)。
この文字列は、その拡張の対象スキーマの名前に(必要なら二重引用符で括られて)置き換えられます。
この表記では、拡張のスクリプトファイルでスキーマ名が固定されているという仮定の必要性は回避されますが、この表記を使用すると、この拡張のインストールされたオブジェクトに他の拡張のスキーマ名を埋め込むことになります。
(通常、これは@extschema:
が関数本体やname
@search_path
設定などの文字列リテラルの内部で使用される場合に発生します。
その他の場合では、オブジェクト参照は解析中にOIDへと縮小され、その後の検索は必要ありません。)
他の拡張のスキーマ名がそのように埋め込まれている場合は、インストール後に他の拡張が再配置されないようにすることが必要です。これを行うには、他の拡張の名前をこの拡張のno_relocate
リストに追加します。
Some extensions include configuration tables, which contain data that might be added or changed by the user after installation of the extension. Ordinarily, if a table is part of an extension, neither the table's definition nor its content will be dumped by <application>pg_dump</application>. But that behavior is undesirable for a configuration table; any data changes made by the user need to be included in dumps, or the extension will behave differently after a dump and restore. 一部の拡張は、拡張をインストールした後でユーザにより追加または変更される可能性があるデータを持つ設定テーブルを含みます。 通常、テーブルが拡張の一部である場合、テーブル定義もその内容もpg_dumpによりダンプされません。 しかしこの振舞いは設定テーブルの場合望まれません。 ユーザによってなされたデータ変更はダンプ内に含まれなければなりません。 さもないとダンプしリストアした後で拡張の動作が変わってしまいます。
To solve this problem, an extension's script file can mark a table
or a sequence it has created as a configuration relation, which will
cause <application>pg_dump</application> to include the table's or the sequence's
contents (not its definition) in dumps. To do that, call the function
<function>pg_extension_config_dump(regclass, text)</function> after creating the
table or the sequence, for example
この問題を解消するために、拡張のスクリプトファイルでは設定リレーションとして作成されるテーブル、またはシーケンスに印を付け、pg_dumpにテーブルの、またはシーケンスの内容をダンプに含める(定義は含まれません)ようにさせることができます。
このためには、以下の例のようにテーブル、またはシーケンスを作成した後にpg_extension_config_dump(regclass, text)
関数を呼び出してください。
CREATE TABLE my_config (key text, value text); CREATE SEQUENCE my_config_seq; SELECT pg_catalog.pg_extension_config_dump('my_config', ''); SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');
Any number of tables or sequences can be marked this way. Sequences
associated with <type>serial</type> or <type>bigserial</type> columns can
be marked as well.
任意数のテーブル、またはシーケンスをこの方法で印付けることができます。
serial
列またはbigserial
列に関連したシーケンスが、同様に印付けることができます。
When the second argument of <function>pg_extension_config_dump</function> is
an empty string, the entire contents of the table are dumped by
<application>pg_dump</application>. This is usually only correct if the table
is initially empty as created by the extension script. If there is
a mixture of initial data and user-provided data in the table,
the second argument of <function>pg_extension_config_dump</function> provides
a <literal>WHERE</literal> condition that selects the data to be dumped.
For example, you might do
pg_extension_config_dump
の第2引数が空文字列である場合、テーブルのすべての内容がpg_dumpによりダンプされます。
これは、拡張のスクリプトによって作成された初期段階においてテーブルが空である場合のみ正しいものです。
テーブルの中で初期データとユーザが提供したデータが混在する場合、pg_extension_config_dump
の第2引数においてダンプすべきデータを選択するWHERE
条件を提供します。
以下に例を示します。
CREATE TABLE my_config (key text, value text, standard_entry boolean); SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
and then make sure that <structfield>standard_entry</structfield> is true only
in the rows created by the extension's script.
このようにした後、拡張のスクリプトで作成される行のみでstandard_entry
が確実に真になるようにします。
For sequences, the second argument of <function>pg_extension_config_dump</function>
has no effect.
シーケンスにおいて、pg_extension_config_dump
の第2引数は何も影響を及ぼしません。
More complicated situations, such as initially-provided rows that might be modified by users, can be handled by creating triggers on the configuration table to ensure that modified rows are marked correctly. 初期状態で提供される行がユーザによって変更されるようなもっと複雑な状況では、設定テーブルに対するトリガを作成して、変更された行が正しく印付けられることを確実にするように取り扱うことができます。
You can alter the filter condition associated with a configuration table
by calling <function>pg_extension_config_dump</function> again. (This would
typically be useful in an extension update script.) The only way to mark
a table as no longer a configuration table is to dissociate it from the
extension with <command>ALTER EXTENSION ... DROP TABLE</command>.
pg_extension_config_dump
を再度呼び出すことにより、設定テーブルに関連付いたフィルタ条件を変更できます。
(通常これは拡張の更新スクリプト内で役に立つでしょう。)
設定ファイルからテーブルを取り除くように印付ける方法は、ALTER EXTENSION ... DROP TABLE
を用いてテーブルを拡張から分離するしかありません。
Note that foreign key relationships between these tables will dictate the order in which the tables are dumped out by pg_dump. Specifically, pg_dump will attempt to dump the referenced-by table before the referencing table. As the foreign key relationships are set up at CREATE EXTENSION time (prior to data being loaded into the tables) circular dependencies are not supported. When circular dependencies exist, the data will still be dumped out but the dump will not be able to be restored directly and user intervention will be required. このテーブルとの外部キーの関係は、テーブルがpg_dumpによってダンプされる順序に影響します。 特に、pg_dumpは参照しているテーブルの前に参照されているテーブルをダンプしようとします。 外部キーの関係はCREATE EXTENSION時(データがテーブルにロードされる前)に設定されますので、循環依存はサポートされません。 循環依存が存在すれば、データはダンプされますが、そのダンプを直接はリストアできず、ユーザの介入が必要になります。
Sequences associated with <type>serial</type> or <type>bigserial</type> columns
need to be directly marked to dump their state. Marking their parent
relation is not enough for this purpose.
serial
列またはbigserial
列に関連したシーケンスは、それらの状態をダンプするために直接印付けする必要があります。
親リレーションを印付けすることは、この目的に十分ではありません。
One advantage of the extension mechanism is that it provides convenient
ways to manage updates to the SQL commands that define an extension's
objects. This is done by associating a version name or number with
each released version of the extension's installation script.
In addition, if you want users to be able to update their databases
dynamically from one version to the next, you should provide
<firstterm>update scripts</firstterm> that make the necessary changes to go from
one version to the next. Update scripts have names following the pattern
<literal><replaceable>extension</replaceable>--<replaceable>old_version</replaceable>--<replaceable>target_version</replaceable>.sql</literal>
(for example, <literal>foo--1.0--1.1.sql</literal> contains the commands to modify
version <literal>1.0</literal> of extension <literal>foo</literal> into version
<literal>1.1</literal>).
拡張機構の1つの利点は、拡張のオブジェクトを定義するSQLコマンドの更新を簡便に管理する方法を提供していることです。
これは、拡張のインストール用スクリプトのリリース版それぞれにバージョン名称またはバージョン番号を関連付けることで行われます。
さらに、ユーザにあるバージョンから次のバージョンへ動的にデータベースを更新させることができるようにしたい場合、あるバージョンから次のバージョンまでの間に行われる必要な変更を行う更新スクリプトを提供しなければなりません。
更新スクリプトは
というパターンに従った名前(例えば、extension
--old_version
--target_version
.sqlfoo--1.0--1.1.sql
はfoo
拡張のバージョン1.0
からバージョン1.1
に変更するコマンドを含みます。)を持たなければなりません。
Given that a suitable update script is available, the command
<command>ALTER EXTENSION UPDATE</command> will update an installed extension
to the specified new version. The update script is run in the same
environment that <command>CREATE EXTENSION</command> provides for installation
scripts: in particular, <varname>search_path</varname> is set up in the same
way, and any new objects created by the script are automatically added
to the extension. Also, if the script chooses to drop extension member
objects, they are automatically dissociated from the extension.
適切な更新スクリプトが利用可能である場合、ALTER EXTENSION UPDATE
コマンドはインストール済みの拡張を指定した新しいバージョンへ更新します。
更新スクリプトは、CREATE EXTENSION
がインストール用スクリプト向けに提供する環境と同じ環境で実行されます。
具体的にはsearch_path
は同じ方法で設定され、スクリプトにより作成される新しいオブジェクトはすべて自動的に拡張に追加されます。
また、スクリプトが拡張のメンバオブジェクトを削除する場合には、それらのメンバオブジェクトは拡張から自動的に分離されます。
If an extension has secondary control files, the control parameters that are used for an update script are those associated with the script's target (new) version. 拡張が副制御ファイルを持つ場合、更新スクリプトで使用される制御パラメータは、スクリプトの対象の(新しい)バージョンに関連付けされたものになります。
<command>ALTER EXTENSION</command> is able to execute sequences of update
script files to achieve a requested update. For example, if only
<literal>foo--1.0--1.1.sql</literal> and <literal>foo--1.1--2.0.sql</literal> are
available, <command>ALTER EXTENSION</command> will apply them in sequence if an
update to version <literal>2.0</literal> is requested when <literal>1.0</literal> is
currently installed.
ALTER EXTENSION
は、要求される更新を実現するために更新スクリプトを連続して実行できます。
例えばfoo--1.0--1.1.sql
とfoo--1.1--2.0.sql
のみが利用可能であるとすると、現在1.0
がインストールされている時にバージョン2.0
への更新が要求された場合、ALTER EXTENSION
はこれらを順番に適用します。
<productname>PostgreSQL</productname> doesn't assume anything about the properties
of version names: for example, it does not know whether <literal>1.1</literal>
follows <literal>1.0</literal>. It just matches up the available version names
and follows the path that requires applying the fewest update scripts.
(A version name can actually be any string that doesn't contain
<literal>--</literal> or leading or trailing <literal>-</literal>.)
PostgreSQLはバージョン名称の特性についてまったく仮定を行いません。
例えば1.0
の次が1.1
であるかどうかを把握しません。
これは利用可能なバージョン名をかみ合わせ、もっとも少ない数の更新スクリプトを適用するために必要な経路を続けるだけです。
(バージョン名には、--
を含まず先頭または最後に-
が付かなければ、任意の文字を取ることができます。)
Sometimes it is useful to provide <quote>downgrade</quote> scripts, for
example <literal>foo--1.1--1.0.sql</literal> to allow reverting the changes
associated with version <literal>1.1</literal>. If you do that, be careful
of the possibility that a downgrade script might unexpectedly
get applied because it yields a shorter path. The risky case is where
there is a <quote>fast path</quote> update script that jumps ahead several
versions as well as a downgrade script to the fast path's start point.
It might take fewer steps to apply the downgrade and then the fast
path than to move ahead one version at a time. If the downgrade script
drops any irreplaceable objects, this will yield undesirable results.
「ダウングレード」スクリプトを提供することが便利な場合があります。
例えばfoo--1.1--1.0.sql
は、バージョン1.1
に関連した変更を元に戻すことができます。
この場合、ダウングレードスクリプトがより短いパスを生成するために、予期せず適用されてしまう可能性に注意してください。
複数のバージョンをまたがって更新する「近道」更新スクリプトと近道の開始バージョンへのダウングレードスクリプトが存在する場合に危険性があります。
ダウングレードしてから近道となる更新スクリプトを実行する方が、バージョンを1つずつ進めるよりも少ない処理で済んでしまうかもしれません。
ダウングレードスクリプトが取り返しがつかないオブジェクトを何か削除してしまう場合、望まない結果になってしまいます。
To check for unexpected update paths, use this command: 想定外の更新経路かどうかを検査するためには、以下のコマンドを使用してください。
SELECT * FROM pg_extension_update_paths('extension_name
');
This shows each pair of distinct known version names for the specified
extension, together with the update path sequence that would be taken to
get from the source version to the target version, or <literal>NULL</literal> if
there is no available update path. The path is shown in textual form
with <literal>--</literal> separators. You can use
<literal>regexp_split_to_array(path,'--')</literal> if you prefer an array
format.
これは指定した拡張の個々の既知のバージョン名の組み合わせをそれぞれ、元のバージョンから対象のバージョンへ進む時に取られる更新経路順、またはもし利用できる更新経路がなければNULL
を付けて、表示します。
経路は--
を区切り文字として使用したテキスト形式で表示されます。
配列形式の方が良ければregexp_split_to_array(path,'--')
を使用できます。
An extension that has been around for awhile will probably exist in
several versions, for which the author will need to write update scripts.
For example, if you have released a <literal>foo</literal> extension in
versions <literal>1.0</literal>, <literal>1.1</literal>, and <literal>1.2</literal>, there
should be update scripts <filename>foo--1.0--1.1.sql</filename>
and <filename>foo--1.1--1.2.sql</filename>.
Before <productname>PostgreSQL</productname> 10, it was necessary to also create
new script files <filename>foo--1.1.sql</filename> and <filename>foo--1.2.sql</filename>
that directly build the newer extension versions, or else the newer
versions could not be installed directly, only by
installing <literal>1.0</literal> and then updating. That was tedious and
duplicative, but now it's unnecessary, because <command>CREATE
EXTENSION</command> can follow update chains automatically.
For example, if only the script
files <filename>foo--1.0.sql</filename>, <filename>foo--1.0--1.1.sql</filename>,
and <filename>foo--1.1--1.2.sql</filename> are available then a request to
install version <literal>1.2</literal> is honored by running those three
scripts in sequence. The processing is the same as if you'd first
installed <literal>1.0</literal> and then updated to <literal>1.2</literal>.
(As with <command>ALTER EXTENSION UPDATE</command>, if multiple pathways are
available then the shortest is preferred.) Arranging an extension's
script files in this style can reduce the amount of maintenance effort
needed to produce small updates.
以前から存在している拡張は、おそらく複数のバージョンに渡って存在しているので、拡張の作者は更新スクリプトを開発する必要性が出てきます。
たとえば、拡張foo
がバージョン1.0
、1.1
、1.2
をリリースしていたとすると、更新スクリプトfoo--1.0--1.1.sql
とfoo--1.1--1.2.sql
が存在しなければなりません。
PostgreSQL 10より前では、新しい拡張のバージョンを直接作成するスクリプトファイルfoo--1.1.sql
とfoo--1.2.sql
も新規に作る必要がありました。
これらがないと、新しいバージョンの拡張を直接インストールすることはできず、1.0
をインストールしてから更新するしかありませんでした。
それにはうんざりしますし、また冗長です。
しかし、今ではCREATE EXTENSION
が自動的に更新連鎖を追跡してくるので、それは不要になりました。
たとえば、foo--1.0.sql
、foo--1.0--1.1.sql
、foo--1.1--1.2.sql
だけしかない場合、バージョン1.2
のインストールのリクエストは、これらのスクリプトを順に実行することによって達成されます。
この手順は、最初に1.0
をインストールして、1.2
にアップデートする場合でも同じです。
(ALTER EXTENSION UPDATE
は、複数の手順がある場合には、最短の手順を選びます。)
この方法で拡張のスクリプトを調整することにより、小さな更新を複数作成するための保守の手間を減らすことができます。
If you use secondary (version-specific) control files with an extension
maintained in this style, keep in mind that each version needs a control
file even if it has no stand-alone installation script, as that control
file will determine how the implicit update to that version is performed.
For example, if <filename>foo--1.0.control</filename> specifies <literal>requires
= 'bar'</literal> but <literal>foo</literal>'s other control files do not, the
extension's dependency on <literal>bar</literal> will be dropped when updating
from <literal>1.0</literal> to another version.
この方法で保守している拡張に二次的な(バージョン固有の)制御ファイルがある場合は、スタンドアローンのインストールスクリプトがない場合でも、各バージョンで制御ファイルが必要になることに注意してください。
そのバージョンへと更新する暗黙的な方法を、制御ファイルが決定するからです。
たとえば、foo--1.0.control
がrequires = 'bar'
を指定しているのに、foo
の他の制御ファイルが指定していないとすると、1.0
から他のバージョンに更新した際にbar
への依存性が削除されてしまうでしょう。
Widely-distributed extensions should assume little about the database they occupy. Therefore, it's appropriate to write functions provided by an extension in a secure style that cannot be compromised by search-path-based attacks. 広く配布される拡張では、インストールされるデータベースについて想定していないはずです。 このため、拡張はサーチパスに基づく攻撃を受けないよう、安全なスタイルで拡張によって提供される関数記述するのが適切です。
An extension that has the <varname>superuser</varname> property set to
true must also consider security hazards for the actions taken within
its installation and update scripts. It is not terribly difficult for
a malicious user to create trojan-horse objects that will compromise
later execution of a carelessly-written extension script, allowing that
user to acquire superuser privileges.
superuser
プロパティを真にしている拡張はインストールや更新スクリプトの中で行われるアクションのセキュリティ面での危険も考慮しなければなりません。
悪意あるユーザが不用意に書かれた拡張スクリプトを悪用してトロイの木馬を作成し、スーパーユーザ権限を獲得できるようにすることは、そう難しくありません。
If an extension is marked <varname>trusted</varname>, then its
installation schema can be selected by the installing user, who might
intentionally use an insecure schema in hopes of gaining superuser
privileges. Therefore, a trusted extension is extremely exposed from a
security standpoint, and all its script commands must be carefully
examined to ensure that no compromise is possible.
拡張がtrusted
と印付けされている場合、そのインストールスキーマはインストールするユーザにより選択できます。そのユーザはスーパーユーザ権限を獲得することを狙って意図的に安全でないスキーマを使用するかもしれません。
したがって、trustedの拡張はセキュリティ観点から極めて危険で、そのスクリプトのコマンドは危険性がないことを確実にするため注意深く検証されなければなりません。
Advice about writing functions securely is provided in <xref linkend="extend-extensions-security-funcs"/> below, and advice about writing installation scripts securely is provided in <xref linkend="extend-extensions-security-scripts"/>. 関数を安全に書くためのアドバイスは以下のリンクから提供されます。 36.17.6.1 また、インストールスクリプトを安全に書くためのアドバイスは以下のリンクから提供されます。 36.17.6.2
SQL-language and PL-language functions provided by extensions are at risk of search-path-based attacks when they are executed, since parsing of these functions occurs at execution time not creation time. 拡張により提供されるSQL言語とPL言語関数は実行されるときにサーチパスに基づく攻撃を受ける危険性があります。 これらの関数は作成時ではなく、実行時に解析されるためです。
The <link linkend="sql-createfunction-security"><command>CREATE
FUNCTION</command></link> reference page contains advice about
writing <literal>SECURITY DEFINER</literal> functions safely. It's
good practice to apply those techniques for any function provided by
an extension, since the function might be called by a high-privilege
user.
CREATE FUNCTION
のリファレンスページにはSECURITY DEFINER
関数を安全に書くためのアドバイスが記載されています。
拡張が提供するあらゆる関数は、強い権限を持つユーザから実行されることがあるので、これらのテクニックを適用することは、良い習慣です。
If you cannot set the <varname>search_path</varname> to contain only
secure schemas, assume that each unqualified name could resolve to an
object that a malicious user has defined. Beware of constructs that
depend on <varname>search_path</varname> implicitly; for
example, <token>IN</token>
and <literal>CASE <replaceable>expression</replaceable> WHEN</literal>
always select an operator using the search path. In their place, use
<literal>OPERATOR(<replaceable>schema</replaceable>.=) ANY</literal>
and <literal>CASE WHEN <replaceable>expression</replaceable></literal>.
search_path
に安全なスキーマだけを設定できない場合は、修飾されていない名前は悪意あるユーザが定義したオブジェクトとして名前解決されうることを想定してください。
暗黙的にsearch_path
に依存する構文に注意してください。
例えば、IN
や CASE
は常にサーチパスを使って演算子を選びます。
これらの場所には、式
WHENOPERATOR(
やスキーマ
.=) ANYCASE WHEN
を使用してください。
式
A general-purpose extension usually should not assume that it's been
installed into a secure schema, which means that even schema-qualified
references to its own objects are not entirely risk-free. For
example, if the extension has defined a
function <literal>myschema.myfunc(bigint)</literal> then a call such
as <literal>myschema.myfunc(42)</literal> could be captured by a
hostile function <literal>myschema.myfunc(integer)</literal>. Be
careful that the data types of function and operator parameters exactly
match the declared argument types, using explicit casts where necessary.
汎用の拡張は通常、安全なスキーマにインストールされることを想定するべきではありません。これはスキーマ修飾された自身のオブジェクトであっても完全にリスクがないわけではないことを意味しています。
例えば、拡張が myschema.myfunc(bigint)
という関数を定義しているとき、myschema.myfunc(42)
というような呼び出しは、悪意ある関数myschema.myfunc(integer)
に捕捉される可能性があります。
必要に応じて明示的なキャストを使用して関数と演算子のデータ型が引数の型と厳密に一致するように注意してください。
An extension installation or update script should be written to guard against search-path-based attacks occurring when the script executes. If an object reference in the script can be made to resolve to some other object than the script author intended, then a compromise might occur immediately, or later when the mis-defined extension object is used. 拡張のインストールや更新スクリプトはスクリプト実行時にサーチパスに基づく攻撃を防ぐように記述されなければなりません。 スクリプトが参照するオブジェクトがスクリプトの作者が意図したものではないオブジェクトとして解決されうる場合、即座もしくは、誤って定義された拡張オブジェクトが使われたときに攻撃を受ける可能性があります。
DDL commands such as <command>CREATE FUNCTION</command>
and <command>CREATE OPERATOR CLASS</command> are generally secure,
but beware of any command having a general-purpose expression as a
component. For example, <command>CREATE VIEW</command> needs to be
vetted, as does a <literal>DEFAULT</literal> expression
in <command>CREATE FUNCTION</command>.
CREATE FUNCTION
やCREATE OPERATOR CLASS
などのDDLコマンドは一般的には安全ですが、汎用的な式を構成に持つコマンドには注意が必要です。
例えば、CREATE FUNCTION
のDEFAULT
式に行うのと同様にCREATE VIEW
には審査が必要です。
Sometimes an extension script might need to execute general-purpose
SQL, for example to make catalog adjustments that aren't possible via
DDL. Be careful to execute such commands with a
secure <varname>search_path</varname>; do <emphasis>not</emphasis>
trust the path provided by <command>CREATE/ALTER EXTENSION</command>
to be secure. Best practice is to temporarily
set <varname>search_path</varname> to <literal>'pg_catalog,
pg_temp'</literal> and insert references to the extension's
installation schema explicitly where needed. (This practice might
also be helpful for creating views.) Examples can be found in
the <filename>contrib</filename> modules in
the <productname>PostgreSQL</productname> source code distribution.
拡張スクリプトには汎用SQLを実行する必要があることがあります。
例えば、DDLではできないカタログの調整などです。
そのようなコマンドは安全なsearch_path
使って実行するように気をつけてください。
CREATE/ALTER EXTENSION
で提供されるパスが安全であると信用しないでください。
最も良い方法は一時的にsearch_path
を'pg_catalog, pg_temp'
にセットし、必要な箇所に明示的に拡張のインストールスキーマの参照を記述する方法です(この方法はビューを作成する場合にも参考になります)。
例は配布されるPostgreSQLソースコードのcontrib
に見つけることができます。
Cross-extension references are extremely difficult to make fully
secure, partially because of uncertainty about which schema the other
extension is in. The hazards are reduced if both extensions are
installed in the same schema, because then a hostile object cannot be
placed ahead of the referenced extension in the installation-time
<varname>search_path</varname>. However, no mechanism currently exists
to require that. For now, best practice is to not mark an extension
trusted if it depends on another one, unless that other one is always
installed in <literal>pg_catalog</literal>.
拡張をまたがる参照を完璧に安全にすることは極めて困難です。
理由の一つに、他の拡張がどのスキーマにあるのか定かではないことがあります。
この危険性は両方の拡張を同じスキーマにインストールすることで軽減できます。
悪意あるオブジェクトをインストール時のsearch_path
内で参照された拡張の前に置くことができないからです。
しかしながら、現時点ではこれを要求するメカニズムはありません。
今のところ、最良の手段は他の拡張に依存する拡張であるなら、依存する拡張が常にpg_catalog
にインストールされるのでない限り、拡張をtrustedと印付けしないことです。
Here is a complete example of an <acronym>SQL</acronym>-only extension, a two-element composite type that can store any type of value in its slots, which are named <quote>k</quote> and <quote>v</quote>. Non-text values are automatically coerced to text for storage. ここでは、SQLのみの拡張の完全な例を示します。 「k」と「v」という名称の2つの要素からなる複合型であり、そのスロットには任意の型の値を格納できるものです。 格納の際テキスト以外の値は自動的にテキストに変換されます。
The script file <filename>pair--1.0.sql</filename> looks like this:
pair--1.0.sql
スクリプトファイルは以下のようになります。
-- complain if script is sourced in psql, rather than via CREATE EXTENSION -- スクリプトが、CREATE EXTENSION経由ではなく、psqlのソースとして使われた場合には文句を言う \echo Use "CREATE EXTENSION pair" to load this file. \quit CREATE TYPE pair AS ( k text, v text ); CREATE FUNCTION pair(text, text) RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;'; CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair); -- "SET search_path" is easy to get right, but qualified names perform better. CREATE FUNCTION lower(pair) RETURNS pair LANGUAGE SQL AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;' SET search_path = pg_temp; CREATE FUNCTION pair_concat(pair, pair) RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k, $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;';
The control file <filename>pair.control</filename> looks like this:
pair.control
制御ファイルは以下のようになります。
# pair extension comment = 'A key/value pair data type' default_version = '1.0' # cannot be relocatable because of use of @extschema@ relocatable = false
While you hardly need a makefile to install these two files into the
correct directory, you could use a <filename>Makefile</filename> containing this:
これらの2つのファイルを正しいディレクトリにインストールするためにmakefileを作成する必要はほとんどありませんが、以下を含むMakefile
を使用できます。
EXTENSION = pair DATA = pair--1.0.sql PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS)
This makefile relies on <acronym>PGXS</acronym>, which is described
in <xref linkend="extend-pgxs"/>. The command <literal>make install</literal>
will install the control and script files into the correct
directory as reported by <application>pg_config</application>.
このmakefileは36.18で説明するPGXSに依存します。
make install
コマンドは制御ファイルとスクリプトファイルをpg_configで報告される正しいディレクトリにインストールします。
Once the files are installed, use the
<command>CREATE EXTENSION</command> command to load the objects into
any particular database.
ファイルがインストールされた後、CREATE EXTENSION
コマンドを使用してオブジェクトを任意の特定のデータベースにロードしてください。