CREATE OPERATOR — 新しい演算子を定義する
CREATE OPERATORname
( {FUNCTION|PROCEDURE} =function_name
[, LEFTARG =left_type
] [, RIGHTARG =right_type
] [, COMMUTATOR =com_op
] [, NEGATOR =neg_op
] [, RESTRICT =res_proc
] [, JOIN =join_proc
] [, HASHES ] [, MERGES ] )
CREATE OPERATOR
は、新しい演算子name
を定義します。
演算子を定義したユーザがその所有者となります。
スキーマ名が指定されていた場合、その演算子は指定したスキーマに作成されます。
スキーマ名が指定されなかった場合、現在のスキーマに作成されます。
演算子名として使用できるのは、以下に示す文字を使った、NAMEDATALEN
-1(デフォルトでは63)文字までの文字列です。
+ - * / < > = ~ ! @ # % ^ & | ` ?
名前の選択には以下に示すいくつかの制約があります。
--
と/*
はコメントの開始とみなされてしまうため、演算子名の一部として使うことができません。
複数の文字からなる演算子名は、下記の文字のうちの1つ以上を含まない限り、+
または-
で終わることができません。
~ ! @ # % ^ & | ` ?
例えば、@-
は演算子名として許されますが、*-
は許されません。
この制約により、PostgreSQLがSQLに準拠する問い合わせをトークン同士の間に空白を要求することなしに解析することが可能になります。
記号=>
はSQL文法で予約されているため、演算子名として使用できません。
演算子!=
は入力時に<>
に変換されるので、これらの2つの名前は常に等価です。
二項演算子では、LEFTARG
とRIGHTARG
の両方を定義しなければなりません。
前置演算子ではRIGHTARG
のみを定義しなければなりません。
function_name
関数は、CREATE FUNCTION
を使って事前に定義されていなければなりません。また、指定された型の正しい数の引数(1つか2つ)を受け付けるよう定義する必要があります。
CREATE OPERATOR
の構文では、キーワードFUNCTION
とPROCEDURE
は等価ですが、参照されている関数はどの場合も関数であって、プロシージャであってはなりません。
ここで、キーワードPROCEDURE
を使用することは歴史的なものであり、廃止予定です。
他の句は演算子最適化用の属性(省略可能)です。 これらの意味は36.15で説明されています。
演算子を作成するためには、引数の型と戻り値の型に対するUSAGE
権限と背後にある関数に対するEXECUTE
権限を持たなければなりません。
交換子または否定子演算子を指定する場合は、それらの演算子を所有していなければなりません。
name
定義される演算子の名前です。
使用できる文字は上を参照してください。
この名前は、例えばCREATE OPERATOR myschema.+ (...)
のように、スキーマ修飾可能です。
修飾されていなければ、演算子は現在のスキーマに作成されます。
異なるデータ型について処理するものであれば、同じスキーマ内の2つの演算子は同じ名前を持つことができます。
これをオーバーロードと言います。
function_name
演算子を実装するために使用する関数です。
left_type
演算子の左オペランドのデータ型です(左オペランドが存在する場合のみ)。 このオプションは前置演算子では省略されます。
right_type
演算子の右オペランドのデータ型です。
com_op
この演算子の交換子です。
neg_op
この演算子の否定子です。
res_proc
この演算子の制約選択評価関数です。
join_proc
この演算子の結合選択評価関数です。
HASHES
この演算子がハッシュ結合をサポートできることを示します。
MERGES
この演算子がマージ結合をサポートできることを示します。
スキーマ修飾された演算子名をcom_op
または他のオプション引数に与えるには、以下の例のようにOPERATOR()
構文を使用してください。
COMMUTATOR = OPERATOR(myschema.===) ,
自己交換演算子を定義するときは、単にそれを行います。 交換演算子の対を定義するときは、少し厄介です。 最初に定義されたものが、まだ定義されていないもう一方を参照できるようにするには、どうすればよいのでしょうか? この問題には3つの解決策があります。
1つ目の方法は、最初の演算子を定義する際にCOMMUTATOR
句を省略し、2番目の演算子の定義で、COMMUTATOR
句に最初の演算子を与えるという方法です。
PostgreSQLは交換演算子が対になっていることが分かっているので、2番目の定義を見た時に、自動的に最初の定義に戻ってその未定義になっているCOMMUTATOR
句を設定します。
もう一つ、より単純な方法は、両方の定義にCOMMUTATOR
句を含めることです。
PostgreSQLが最初の定義を処理し、COMMUTATOR
が存在しない演算子を参照していることに気付いた場合、システムカタログ内にその演算子のダミーエントリを作成します。
このダミーエントリは、演算子名、左右のオペランド型、および所有者に対してのみ有効なデータを持ちます。
PostgreSQLが現時点で推論できるのはこれだけです。
最初のオペレータのカタログエントリは、このダミーエントリにリンクします。
後で2番目の演算子を定義すると、システムは2番目の定義からの追加情報でダミーエントリを更新します。
追加情報が入力される前にダミー演算子を使用しようとすると、エラーメッセージが表示されます。
あるいは、両方の演算子をCOMMUTATOR
句なしで定義し、その後でALTER OPERATOR
を使用して、それらの交換子リンクを設定できます。
対のどちらか一方をALTER
することで十分です。
3つの場合すべてにおいて、それらを交換子として印付けするために両方の演算子を所有していることが必要です。
否定子演算子の対は、交換子の対と同じ方法で定義できます。
CREATE OPERATOR
で演算子の語彙優先順位を指定することはできません。
パーサの優先順位に関する動作は固定であるためです。
詳細な優先順位については4.1.6を参照してください。
廃止されたオプションSORT1
、SORT2
、LTCMP
、およびGTCMP
は、マージ結合可能演算子に関連したソート演算子の名前を指定するために使用されていました。
代わりにB-tree演算子族を検索することで関連する演算子の情報を見つけることができるようになりましたので、これは必要がなくなりました。
これらの内のいずれかのオプションが指定された場合、暗黙的にMERGES
を真に設定するだけで、それ以外は無視します。
データベースからユーザ定義の演算子を削除するにはDROP OPERATOR
を使用してください。
データベース内の演算子を変更するにはALTER OPERATOR
を使用してください。
以下のコマンドは、データ型box
に対する領域等価性を判定する新しい演算子を定義します。
CREATE OPERATOR === ( LEFTARG = box, RIGHTARG = box, FUNCTION = area_equal_function, COMMUTATOR = ===, NEGATOR = !==, RESTRICT = area_restriction_function, JOIN = area_join_function, HASHES, MERGES );
CREATE OPERATOR
はPostgreSQLの拡張です。
標準SQLには、ユーザ定義の演算子についての規定はありません。