<!--
$Header: /usr/prj/pg/cvsroot/doc/doc/src/sgml/ref/create_operator.sgml,v 1.6 2001/09/06 09:49:18 i-kaori Exp $
Postgres documentation
-->

<refentry id="SQL-CREATEOPERATOR">
 <refmeta>
  <refentrytitle id="sql-createoperator-title">
   CREATE OPERATOR
  </refentrytitle>
  <refmiscinfo>SQL<!-- Language Statements -->言語</refmiscinfo>
 </refmeta>
 <refnamediv>
  <refname>
   CREATE OPERATOR
  </refname>
  <refpurpose>
   <!-- Defines a new user operator -->
   新しいユーザー演算子を定義します。<indexterm><primary>CREATE OPERATOR</primary></indexterm><indexterm><primary>SQL</primary><secondary>CREATE OPERATOR</secondary></indexterm><indexterm><primary sortas="えんざんし">演算子</primary><secondary sortas="ゆーざーていぎ">ユーザー定義</secondary></indexterm>
  </refpurpose>
  </refnamediv>
 <refsynopsisdiv>
  <refsynopsisdivinfo>
   <date>2000-03-25</date>
  </refsynopsisdivinfo>
<synopsis>
CREATE OPERATOR <replaceable>name</replaceable> ( PROCEDURE = <replaceable class="parameter">func_name</replaceable>
     [, LEFTARG = <replaceable class="parameter">type1</replaceable> ] [, RIGHTARG = <replaceable class="parameter">type2</replaceable> ]
     [, COMMUTATOR = <replaceable class="parameter">com_op</replaceable> ] [, NEGATOR = <replaceable class="parameter">neg_op</replaceable> ]
     [, RESTRICT = <replaceable class="parameter">res_proc</replaceable> ] [, JOIN = <replaceable class="parameter">join_proc</replaceable> ]
     [, HASHES ] [, SORT1 = <replaceable class="parameter">left_sort_op</replaceable> ] [, SORT2 = <replaceable class="parameter">right_sort_op</replaceable> ] )
</synopsis>
  
  <refsect2 id="R2-SQL-CREATEOPERATOR-1">
   <refsect2info>
    <date>2000-03-25</date>
   </refsect2info>
   <title>
    <!-- Inputs -->入力
   </title>

    <variablelist>
     <varlistentry>
      <term><replaceable class="parameter">name</replaceable></term>
      <listitem>
       <para>
        <!-- 
	The operator to be defined. See below for allowable characters. -->
        定義される演算子です。使用できる文字は下記を参照してください。
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">func_name</replaceable></term>
      <listitem>
       <para>
	<!-- The function used to implement this operator. -->
        この演算子を実装するために使われる関数です。
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">type1</replaceable></term>
      <listitem>
       <para>
        <!-- 
	The type of the left-hand argument of the operator, if any.
	This option would be omitted for a left-unary operator. -->

        もしある場合は、演算子の左辺の引数の型です。このオプションは左単項演算子では省略されます。

       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">type2</replaceable></term>
      <listitem>
       <para>
        <!-- 
	The type of the right-hand argument of the operator, if any.
	This option would be omitted for a right-unary operator. -->

        もしある場合は、演算子の右辺の引数の型です。このオプションは右単項演算子では省略されます。

       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">com_op</replaceable></term>
      <listitem>
       <para>
	<!-- The commutator of this operator. -->
        この演算子の交代演算子です。
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">neg_op</replaceable></term>
      <listitem>
       <para>
	<!-- The negator of this operator. -->
        この演算子の否定子です。
       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">res_proc</replaceable></term>
      <listitem>
       <para>
	<!-- The restriction selectivity estimator function for this operator.
        -->

        この演算子の制約選択評価関数です。<indexterm><primary sortas="せいやくせんたくひょうかかんすう">制約選択評価関数</primary></indexterm><indexterm><primary sortas="えんざんし">演算子</primary><secondary sortas="せいやくせんたくひょうかかんすう">制約選択評価関数</secondary></indexterm>

       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">join_proc</replaceable></term>
      <listitem>
       <para>
	<!-- The join selectivity estimator function for this operator.
        -->

        この演算子の結合選択評価関数です。<indexterm><primary sortas="けつごうせんたくひょうかかんすう">結合選択評価関数</primary></indexterm><indexterm><primary sortas="えんざんし">演算子</primary><secondary sortas="けつごうせんたくひょうかかんすう">結合選択評価関数</secondary></indexterm>

       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term>HASHES</term>
      <listitem>
       <para>
       <!-- Indicates this operator can support a hash join. -->

        この演算子がハッシュ結合をサポートできることを示します。

       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">left_sort_op</replaceable></term>
      <listitem>
       <para>
	<!-- If this operator can support a merge join, the
	operator that sorts the left-hand data type of this operator.
        -->

        その演算子がマージ結合をサポートできる場合、その演算子の左辺データ型をソートする演算子です。

       </para>
      </listitem>
     </varlistentry>
     <varlistentry>
      <term><replaceable class="parameter">right_sort_op</replaceable></term>
      <listitem>
       <para>
	<!-- If this operator can support a merge join, the
	operator that sorts the right-hand data type of this operator. -->

        この演算子がマージ結合をサポートできる場合、その演算子の右辺データ型をソートする演算子です。

       </para>
      </listitem>
     </varlistentry>
    </variablelist>
  </refsect2>

  <refsect2 id="R2-SQL-CREATEOPERATOR-2">
   <refsect2info>
    <date>2000-03-25</date>
   </refsect2info>
   <title>
    <!-- Outputs -->出力
   </title>
    <variablelist>
     <varlistentry>
      <term><computeroutput>
CREATE
       </computeroutput></term>
      <listitem>
       <para>
	<!-- Message returned if the operator is successfully created. -->
        演算子の作成に成功した場合に返されるメッセージです。

       </para>
      </listitem>
     </varlistentry>
    </variablelist>
  </refsect2>
 </refsynopsisdiv>

 <refsect1 id="R1-SQL-CREATEOPERATOR-1">
  <refsect1info>
   <date>2000-03-25</date>
  </refsect1info>
  <title>
   <!-- Description -->説明
  </title>
  <para>
   <!-- <command>CREATE OPERATOR</command>  defines a new operator,
   <replaceable class="parameter">name</replaceable>.
   The user who defines an operator becomes its owner. -->

   <command>CREATE OPERATOR</command>は、新しい演算子<replaceable class="parameter">name</replaceable>を定義します。演算子を定義したユーザーがその所有者となります。

  </para>
  <para>
   <!-- 
   The operator <replaceable class="parameter">name</replaceable>
   is a sequence of up to NAMEDATALEN-1 (31 by default) characters
   from the following list: -->

   演算子<replaceable class="parameter">name</replaceable>は、以下に示す文字で、NAMEDATALEN-1（デフォルトでは31）文字数までの文字列です。
</para>

   <literallayout>
+ - * / &lt; &gt; = ~ ! @ # % ^ &amp; | ` ? $
   </literallayout>

<para>
   <!-- There are a few restrictions on your choice of name: -->
   名前の選択には以下に示すいくつかの制約があります。
 </para>
 
   <itemizedlist>
    <listitem>
     <para>
     <!-- "$" cannot be defined as a single-character operator,
     although it can be part of a multi-character operator name. -->

     「$」は、複数文字の演算子名の一部になることはできますが、単一文字の演算子として定義することはできません。

     </para>
    </listitem>
    <listitem>
     <para>
     <!-- "__" and "/*" cannot appear anywhere in an operator name,
     since they will be taken as the start of a comment. -->

     「--」と「/*」は演算子名のどこにも使うことができません。コメントの開始とみなれてしまうからです。

     </para>
    </listitem>
    <listitem>
     <para>
     <!-- 
     A multi-character operator name cannot end in "+" or "-",
     unless the name also contains at least one of these characters: -->

     複数文字の演算子の名前は、下記のうちの1つ以上を含まない限り「+」または「-」で終わることができません。 

     <literallayout>
~ ! @ # % ^ &amp; | ` ? $
     </literallayout>
     <!-- 
     For example, <literal>@-</literal> is an allowed operator name,
     but <literal>*-</literal> is not.
     This restriction allows <productname>Postgres</productname> to
     parse SQL-compliant queries without requiring spaces between tokens.
     -->

     たとえば、「<literal>@-</literal>」は演算子名として許可されますが、「<literal>*-</literal>」は許可されません。この制約により、<productname>Postgres</productname>がSQLに準拠する問い合わせをトークン同士の間にスペースを要求することなしに解析することが可能になります。
  
     </para>
    </listitem>
   </itemizedlist>

   <note>
    <para>
     <!-- 
     When working with non-SQL-standard operator names, you will usually
     need to separate adjacent operators with spaces to avoid ambiguity.
     For example, if you have defined a left-unary operator named "@",
     you cannot write <literal>X*@Y</literal>; you must write
     <literal>X* @Y</literal> to ensure that
     <productname>Postgres</productname> reads it as two operator names
     not one. -->

     非SQL標準の演算子名を使って作業する場合、通常はあいまいさを避けるために隣接する演算子をスペースで区切る必要があります。たとえば、「@」という名前の左単項演算子を定義した場合、<literal>X*@Y</literal>と書くことはできません。<productname>Postgres</productname>が1つではなく確実に2つの演算子として読むためには<literal>X* @Y</literal>と書かなければなりません。

     </para>
   </note>   

  <para>
   <!-- 
   The operator "!=" is mapped to "&lt;&gt;" on input, so these two names
   are always equivalent. -->

   演算子「!=」は入力では「&lt;&gt;」に写像されるので、これらの2つの名前は常に等価です。

  </para>
  <para>
   <!-- 
   At least one of LEFTARG and RIGHTARG must be defined.  For
   binary operators, both should be defined. For right  unary
   operators,  only  LEFTARG  should  be defined, while for left
   unary operators only RIGHTARG should be defined. -->

   少なくともLEFTARGとRIGHTARGのどちらかは定義されなければなりません。二項演算子では両方が定義されなければなりません。右単項演算子ではLEFTARGのみが定義されなければならず、左単項演算子ではRIGHTARGのみが定義されなければなりません。

  </para>
  <para>
   <!-- The
   <replaceable class="parameter">func_name</replaceable> procedure must have
   been previously defined using <command>CREATE FUNCTION</command> and  must
   be defined to accept the correct number of arguments
   (either one or two) of the indicated types. -->

   <replaceable class="parameter">func_name</replaceable>プロシージャは、<command>CREATE FUNCTION</command>を使って事前に定義されていなければならず、指定された型の正しい数の引数（1つか2つ）を受け付けるように定義されていなければなりません。

  </para>
  <para>
   <!-- The commutator operator should be identified if one exists,
   so that <productname>Postgres</productname> can
   reverse the order of the operands if it wishes.
   For example, the operator area-less-than, &lt;&lt;&lt;,
   would probably have a commutator
   operator, area-greater-than, &gt;&gt;&gt;.
   Hence, the query optimizer could freely  convert: -->

   存在する場合、交代演算子は、<productname>Postgres</productname>が必要に応じて演算項目の順序を反転できるように認識させておくべきです。たとえば、領域に対する「より小さい」を判定する演算子「&lt;&lt;&lt;」はおそらく、領域に対する「より大きい」を判定する演算子「&gt;&gt;&gt;を」交代演算子として持つでしょう。これにより、問い合わせオプティマイザは自由に以下の文を、その次の文に置き換えることができます。
</para>

<programlisting>
box '((0,0), (1,1))'  &gt;&gt;&gt; MYBOXES.description
</programlisting>


<programlisting>
MYBOXES.description &lt;&lt;&lt; box '((0,0), (1,1))'
</programlisting>

  <para>
   <!-- This  allows  the  execution code to always use the latter
   representation and simplifies the  query  optimizer  somewhat. -->

   これは実行コードが常に後者の表記を使うようにでき、問い合わせオプティマイザをいくらか単純にすることができます。

  </para>
  <para>
   <!-- 
   Similarly, if there is a negator operator then it should be
   identified.
   Suppose  that  an
   operator,  area-equal, ===, exists, as well as an area not
   equal, !==.
   The negator link allows the query optimizer to simplify -->

   同様に、もし否定子がある場合はそれは認識されておくべきです。たとえば、領域の「等しい」を判定する演算子「===」、が領域の「等しくない」を判定する演算子「!==」と一緒に存在したとします。否定子の関係により、問い合わせオプティマイザは以下の文を、その次の文に単純化することができます。
</para>

<programlisting>
NOT MYBOXES.description === box '((0,0), (1,1))'
</programlisting>
   <!-- to -->
<programlisting>
MYBOXES.description !== box '((0,0), (1,1))'
</programlisting>

  <para>
   <!-- If  a  commutator  operator  name  is  supplied,  
   <productname>Postgres</productname>
   searches  for  it  in  the catalog.  If it is found and it
   does not yet have a commutator itself, then the commutator's
   entry is updated to have the newly created operator as its
   commutator.  This applies to the negator, as well.
   This  is to allow the definition of two operators that are
   the commutators or the negators of each other.  The  first
   operator should be defined without a commutator or negator
   (as appropriate).  When the second  operator  is  defined,
   name  the  first  as the commutator or negator.  The first
   will be updated as a side effect.  (As of Postgres 6.5,
   it also works to just have both operators refer to each other.)
   -->

   交代演算子名が与えられた場合、<productname>Postgres</productname>はカタログの中からそれを探します。検出された交代演算子名の交代演算子がまだ存在しない場合、交代演算子のエントリは新しく作られた演算子をその交代演算子として持つように更新されます。これは否定子にも適用されます。互いの交代演算子または否定子である2つの演算子の定義を許可するためです。最初の演算子は交代演算子や否定子（のどちらか適切なもの）なしで定義されなければなりません。2番目の演算子が定義されるときに、最初の演算子を交代演算子または否定子として指定します。副作用として最初の演算子は更新されます（Postgres 6.5以降では、両方の演算子がお互いを参照するようにすることもできます）。<indexterm><primary sortas="こうたいえんざんし">交代演算子</primary></indexterm><indexterm><primary sortas="えんざんし">演算子</primary><secondary sortas="こうたいえんざんし">交代演算子</secondary></indexterm>
  </para>
  <para>
   <!-- 
   The HASHES, SORT1, and SORT2 options are  present  to  support  the
   query  optimizer in performing joins.  
   <productname>Postgres</productname> can always
   evaluate a join (i.e., processing a clause with two  tuple
   variables separated by an operator that returns a boolean)
   by iterative substitution [WONG76].  
   In addition, <productname>Postgres</productname>
   can use a hash-join algorithm along
   the lines of [SHAP86]; however, it must know whether  this
   strategy  is  applicable.   The current hash-join algorithm
   is only correct for operators that represent equality tests;
   furthermore, equality of the data type must mean bitwise equality
   of the representation of the type.  (For example, a data type that
   contains unused bits that don't matter for equality tests could
   not be hashjoined.)
   The HASHES flag indicates to the query optimizer that a hash join
   may safely be used with this operator. -->

   オプションHASHES、SORT1、SORT2は結合の実行で問い合わせオプティマイザをサポートするために存在します。<productname>Postgres</productname>は常に反復置換[WONG76]（つまり、ブール値を返す演算子によって分離された2つのタプル変数を持つ句の処理）により結合を評価できます。このほかに、<productname>Postgres</productname>は[SHAP86]に従ったハッシュ結合アルゴリズムを使用することができます。とはいえ、どちらの戦略が適用できるかどうかを知る必要があります。現在のハッシュ結合アルゴリズムは等価性の評価を示す演算子のみに対して有効です。さらに、データ型の等価性は、型の表現形式がビット単位で等しいことを意味していなければなりません（たとえば、等価性の評価に関係のない未使用のビットを含んでいるデータ型はハッシュ結合させることができません）。HASHESのフラグは問い合わせオプティマイザに対し、ハッシュ結合がこの演算子で安全に使用できることを示します。 
  
</para>
  <para>
   <!-- 
   Similarly, the two sort operators indicate  to  the  query
   optimizer whether merge-sort is a usable join strategy and
   which operators should be used  to  sort  the  two  operand
   classes.  Sort operators should only be provided for an equality
   operator, and they should refer to less-than operators for the
   left and right side data types respectively. -->

   同様にして、2つのソート演算子は問い合わせオプティマイザに対し、マージソートが結合戦略で有効かどうか、そしてどちらの演算子が2つの演算項目クラスに対して使用されるのかを示します。ソート演算子は等価演算子に対してのみ提供されなければならず、それぞれが右辺と左辺のデータ型に対する「より小さい」を評価する演算子を参照しなければなりません。 

  </para>
  <para>
   <!-- If  other join strategies are found to be practical,
   <productname>Postgres</productname>
   will change the optimizer and run-time system to  use
   them  and  will  require  additional specification when an
   operator is defined.  Fortunately, the research  community
   invents  new  join  strategies infrequently, and the added
   generality of user-defined join strategies was not felt to
   be worth the complexity involved. -->

   他の結合戦略が実用的であった場合、<productname>Postgres</productname>はその戦略を使用するようにオプティマイザと実行システムを変更し、ある演算子が定義されたときに追加仕様を求めることになります。幸運なことに、研究団体が新しい結合戦略を発明することは滅多になく、追加されるユーザー定義の結合戦略の大部分は、その複雑さほどに価値があるとは思えません。

  </para>
  <para>
   <!-- 
   The RESTRICT and JOIN options assist the query optimizer in estimating
   result sizes.  If a clause of the form: -->

   RESTRICTとJOINオプションは問い合わせオプティマイザの結果サイズの推定を補助します。もし、下記のような形式の句が条件の中にある場合、<productname>Postgres</productname>はこの句を満たすMYBOXESにあるインスタンスの割合を推測する必要があります。
</para>

<programlisting>
MYBOXES.description &lt;&lt;&lt; box '((0,0), (1,1))'
</programlisting>

<para>
   <!-- is present in the qualification,
   then <productname>Postgres</productname> may have to
   estimate the fraction of the  instances  in  MYBOXES  that
   satisfy  the clause.  The function
   <replaceable class="parameter">res_proc</replaceable>
   must be a registered function (meaning  it  is  already  defined  using
   <command>CREATE FUNCTION</command>) which accepts arguments of the correct
   data types and returns a floating point  number.   The
   query  optimizer  simply  calls this function, passing the
   parameter <literal>((0,0), (1,1))</literal> and multiplies the result by the relation
   size to get the expected number of instances. -->

   <replaceable class="parameter">res_proc</replaceable>関数は、正確なデータ型の引数をとり、浮動小数点数値を返す、登録された（すでに<command>CREATE FUNCTION</command>を使って定義された）関数でなければなりません。問い合わせオプティマイザは単にこの関数を<literal>((0,0), (1,1))</literal>というパラメータを渡して呼び出し、その結果にリレーションのサイズを掛け、インスタンス数の期待値を入手します。

  </para>
  <para>
   <!-- 
   Similarly, when the operands of the operator both  contain
   instance  variables, the query optimizer must estimate the
   size of the resulting join.  The function  join_proc  will
   return  another floating point number which will be multiplied
   by the cardinalities of the two tables involved  to
   compute the expected result size. -->

   同様に、演算子の演算項目が2つともインスタンス変数を持っている場合、問い合わせオプティマイザは結合の結果のサイズを推測しなければなりません。関数join_procは結果サイズの期待値を計算するために、関係する2つのテーブルの要素数によって乗算された別の浮動小数点数値を返します。 

  </para>
  <para>
   <!-- The difference between the function -->
   以下のような関数があるとします。
</para>

<programlisting>
my_procedure_1 (MYBOXES.description, box '((0,0), (1,1))')
</programlisting>

<para>
   <!-- and the operator -->
   上記の関数と、以下の演算子との違いは<productname>Postgres</productname>が演算子の最適化を図り、演算子が呼び出されたときに、検索空間を制限するためにインデックスを使用するかどうかを決定できることです。
</para>

<programlisting>
MYBOXES.description === box '((0,0), (1,1))'
</programlisting>

<para>
   <!-- is  that  <productname>Postgres</productname>
   attempts to optimize operators and can
   decide to use an index to restrict the search  space  when
   operators  are  involved.  However, there is no attempt to
   optimize functions, and they are performed by brute force.
   Moreover, functions can have any number of arguments while
   operators are restricted to one or two. -->

   しかしながら、関数を最適化することはせず、力任せに処理されます。さらに、演算子は1つまたは2つまでと引数の数が制限されているのに対して、関数はどんな数の引数でも取ることができます。 

  </para>
  
  <refsect2 id="R2-SQL-CREATEOPERATOR-3">
   <refsect2info>
    <date>2000-03-25</date>
   </refsect2info>
   <title>
    <!-- Notes -->注釈
   </title>
   <para>
    <!-- Refer to the chapter on operators in the
    <citetitle>PostgreSQL User's Guide</citetitle>
    for further information.
    Refer to <command>DROP OPERATOR</command> to delete
    user-defined operators from a database. -->

    詳細については<citetitle>&user-guide;</citetitle>の演算子の章を参照してください。ユーザー定義の演算子をデータベースから削除する場合は<command>DROP OPERATOR</command>を参照してください。

   </para>
  </refsect2>
 </refsect1>
  
 <refsect1 id="R1-SQL-CREATEOPERATOR-2">
  <title>
   <!-- Usage -->使用方法
  </title>
  <para><!-- The following command defines a new operator,
   area-equality, for the BOX data type: -->

   以下のコマンドは、BOXデータ型に対する領域等価性を判定する新しい演算子を定義します。

  </para>
<programlisting>
CREATE OPERATOR === (
   LEFTARG = box,
   RIGHTARG = box,
   PROCEDURE = area_equal_procedure,
   COMMUTATOR = ===,
   NEGATOR = !==,
   RESTRICT = area_restriction_procedure,
   JOIN = area_join_procedure,
   HASHES,
   SORT1 = <<<,
   SORT2 = <<<
);
</programlisting>  
 </refsect1>
 
 <refsect1 id="R1-SQL-CREATEOPERATOR-3">
  <title>
   <!-- Compatibility -->互換性
  </title>
  
  <refsect2 id="R2-SQL-CREATEOPERATOR-4">
   <refsect2info>
    <date>2000-03-25</date>
   </refsect2info>
   <title>
    SQL92
   </title>

   <para>
    <!-- <command>CREATE OPERATOR</command>
    is a <productname>Postgres</productname> extension.
    There is no <command>CREATE OPERATOR</command>
    statement in <acronym>SQL92</acronym>. -->

    <command>CREATE OPERATOR</command>は<productname>Postgres</productname>の拡張です。<acronym>SQL92</acronym>には<command>CREATE OPERATOR</command>文はありません。

   </para>
  </refsect2>
 </refsect1>
</refentry>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:nil
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:"../reference.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:"/usr/lib/sgml/catalog"
sgml-local-ecat-files:nil
End:
-->
