aboutsummaryrefslogtreecommitdiff
path: root/doc/src/sgml/ref/create_operator.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/ref/create_operator.sgml')
-rw-r--r--doc/src/sgml/ref/create_operator.sgml416
1 files changed, 416 insertions, 0 deletions
diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml
new file mode 100644
index 00000000000..a9c25a02692
--- /dev/null
+++ b/doc/src/sgml/ref/create_operator.sgml
@@ -0,0 +1,416 @@
+<REFENTRY ID="SQL-CREATEOPERATOR-1">
+ <REFMETA>
+ <REFENTRYTITLE>
+ CREATE OPERATOR
+ </REFENTRYTITLE>
+ <REFMISCINFO>SQL - Language Statements</REFMISCINFO>
+ </REFMETA>
+ <REFNAMEDIV>
+ <REFNAME>
+ CREATE OPERATOR
+ </REFNAME>
+ <REFPURPOSE>
+ Defines a new user operator.
+ </REFPURPOSE>
+
+ <REFSYNOPSISDIV>
+ <REFSYNOPSISDIVINFO>
+ <DATE>1998-04-15</DATE>
+ </REFSYNOPSISDIVINFO>
+ <SYNOPSIS>
+ CREATE OPERATOR <replaceable>name</replaceable>
+ ([ LEFTARG = <replaceable class="parameter">type1</replaceable> ]
+ [, RIGHTARG = <replaceable class="parameter">type2</replaceable> ]
+ , PROCEDURE = <replaceable class="parameter">func_name</replaceable>
+ [, COMMUTATOR = <replaceable class="parameter">com_op</replaceable> ]
+ [, NEGATOR = <replaceable class="parameter">neg_op</replaceable> ]
+ [, RESTRICT = <replaceable class="parameter">res_proc</replaceable> ]
+ [, HASHES ]
+ [, JOIN = <replaceable class="parameter">join_proc</replaceable> ]
+ [, SORT = <replaceable class="parameter">sort_op</replaceable> [, ...] ]
+ )
+ </SYNOPSIS>
+
+ <REFSECT2 ID="R2-SQL-CREATEOPERATOR-1">
+ <REFSECT2INFO>
+ <DATE>1998-04-15</DATE>
+ </REFSECT2INFO>
+ <TITLE>
+ Inputs
+ </TITLE>
+ <PARA>
+ </PARA>
+ <VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ <VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">name</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ The name of an existing aggregate function.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">type1</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">type2</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">func_name</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">com_op</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">neg_op</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">res_proc</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">join_proc</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ <VARLISTENTRY>
+ <TERM>
+ <replaceable class="parameter">sort_op</replaceable>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ </variablelist>
+ </LISTITEM>
+ </VARLISTENTRY>
+ </VARIABLELIST>
+ </REFSECT2>
+
+ <REFSECT2 ID="R2-SQL-CREATEOPERATOR-2">
+ <REFSECT2INFO>
+ <DATE>1998-04-15</DATE>
+ </REFSECT2INFO>
+ <TITLE>
+ Outputs
+ </TITLE>
+ <PARA>
+ </PARA>
+ <VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ <VARIABLELIST>
+ <VARLISTENTRY>
+ <TERM>
+ <ReturnValue>CREATE</ReturnValue>
+ </TERM>
+ <LISTITEM>
+ <PARA>
+ Message returned if the operator is successfully created.
+ </PARA>
+ </LISTITEM>
+ </VARLISTENTRY>
+ </variablelist>
+ </LISTITEM>
+ </VARLISTENTRY>
+ </VARIABLELIST>
+ </REFSECT2>
+ </REFSYNOPSISDIV>
+
+ <REFSECT1 ID="R1-SQL-CREATEOPERATOR-1">
+ <REFSECT1INFO>
+ <DATE>1998-04-15</DATE>
+ </REFSECT1INFO>
+ <TITLE>
+ Description
+ </TITLE>
+ <PARA>
+ This command defines a new user operator, operator_name.
+ The user who defines an operator becomes its owner.
+ </para>
+ <para>
+ The operator_name is a sequence of up to sixteen punctua
+ tion characters. The following characters are valid for
+ single-character operator names:<literallayout>
+
+ ~ ! @ # % ^ & ` ? </literallayout>
+ </para>
+ <para>
+ If the operator name is more than one character long, it
+ may consist of any combination of the above characters or
+ the following additional characters:<literallayout>
+
+ | $ : + - * / &lt; &gt; =</literallayout>
+ </para>
+ <para>
+ The operator "!=" is mapped to "&lt;&gt;" on input, and they are
+ therefore equivalent.
+ </para>
+ <para>
+ At least one of leftarg and rightarg must be defined. For
+ binary operators, both should be defined. For right unary
+ operators, only arg1 should be defined, while for left
+ unary operators only arg2 should be defined.
+ </para>
+ <para>
+ The name of the operator, operator_name, can be composed
+ of symbols only. Also, the func_name procedure must have
+ been previously defined using create function(l) and must
+ have one or two arguments.
+ </para>
+ <para>
+ The commutator operator is present so that Postgres can
+ reverse the order of the operands if it wishes. For exam
+ ple, the operator area-less-than, >>>, would have a commu
+ tator operator, area-greater-than, <<<. Suppose that an
+ operator, area-equal, ===, exists, as well as an area not
+ equal, !==. Hence, the query optimizer could freely con
+ vert:
+ <programlisting>
+ "0,0,1,1"::box >>> MYBOXES.description
+ </programlisting>
+ to
+ <programlisting>
+ MYBOXES.description <<< "0,0,1,1"::box</programlisting>
+ </para>
+ <para>
+ This allows the execution code to always use the latter
+ representation and simplifies the query optimizer some
+ what.
+ </para>
+ <para>
+ The negator operator allows the query optimizer to convert
+ <programlisting>
+ NOT MYBOXES.description === "0,0,1,1"::box
+ </programlisting>
+ to
+ <programlisting>
+ MYBOXES.description !== "0,0,1,1"::box
+ </programlisting>
+ </para>
+ <para>
+ If a commutator operator name is supplied, Postgres
+ 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 current (new) operator
+ as its commutator. This applies to the negator, as well.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ The next two specifications are present to support the
+ query optimizer in performing joins. Postgres 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, Postgres
+ is planning on implementing a hash-join algorithm along
+ the lines of [SHAP86]; however, it must know whether this
+ strategy is applicable. For example, a hash-join
+ algorithm is usable for a clause of the form:
+ <programlisting>
+ MYBOXES.description === MYBOXES2.description
+ </programlisting>
+ but not for a clause of the form:
+ <programlisting>
+ MYBOXES.description <<< MYBOXES2.description.
+ </programlisting>
+ The hashes flag gives the needed information to the query
+ optimizer concerning whether a hash join strategy is
+ usable for the operator in question.</para>
+ <para>
+ Similarly, the two sort operators indicate to the query
+ optimizer whether merge-sort is a usable join strategy and
+ what operators should be used to sort the two operand
+ classes. For the === clause above, the optimizer must
+ sort both relations using the operator, <<<. On the other
+ hand, merge-sort is not usable with the clause:
+ <programlisting>
+ MYBOXES.description <<< MYBOXES2.description
+ </programlisting>
+ </para>
+ <para>
+ If other join strategies are found to be practical, Post
+ gres 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.
+ </para>
+ <para>
+ The last two pieces of the specification are present so
+ the query optimizer can estimate result sizes. If a
+ clause of the form:
+ <programlisting>
+ MYBOXES.description <<< "0,0,1,1"::box
+ </programlisting>
+ is present in the qualification, then Postgres may have to
+ estimate the fraction of the instances in MYBOXES that
+ satisfy the clause. The function res_proc must be a reg
+ istered function (meaning it is already defined using
+ define function(l)) which accepts one argument of the correct
+ data type and returns a floating point number. The
+ query optimizer simply calls this function, passing the
+ parameter "0,0,1,1" and multiplies the result by the relation
+ size to get the desired expected number of instances.
+ </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 classes involved to
+ compute the desired expected result size.
+ </para>
+ <para>
+ The difference between the function
+ <programlisting>
+ my_procedure_1 (MYBOXES.description, "0,0,1,1"::box)
+ </programlisting>
+ and the operator
+ <programlisting>
+ MYBOXES.description === "0,0,1,1"::box
+ </programlisting>
+ is that Postgres 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.
+ </PARA>
+
+ <REFSECT2 ID="R2-SQL-CREATEOPERATOR-3">
+ <REFSECT2INFO>
+ <DATE>1998-04-15</DATE>
+ </REFSECT2INFO>
+ <TITLE>
+ Notes
+ </TITLE>
+ <PARA>
+ Refer to <citetitle>PostgreSQL User's Guide</citetitle> chapter 5
+ <comment>
+ This reference must be corrected.
+ </comment>
+ for further information.
+ Refer to DROP OPERATOR statement to drop operators.
+
+ </REFSECT2>
+
+ <REFSECT1 ID="R1-SQL-CREATEOPERATOR-2">
+ <TITLE>
+ Usage
+ </TITLE>
+ <PARA>The following command defines a new operator,
+ area-equality, for the BOX data type.
+ </PARA>
+ <ProgramListing>
+ CREATE OPERATOR === (
+ LEFTARG = box,
+ RIGHTARG = box,
+ PROCEDURE = area_equal_procedure,
+ COMMUTATOR = ===,
+ NEGATOR = !==,
+ RESTRICT = area_restriction_procedure,
+ HASHES,
+ JOIN = area-join-procedure,
+ SORT = <<<, <<<)
+ </ProgramListing>
+
+
+ </REFSECT1>
+
+ <REFSECT1 ID="R1-SQL-CREATEOPERATOR-3">
+ <TITLE>
+ Compatibility
+ </TITLE>
+ <PARA>
+ CREATE OPERATOR is a PostgreSQL extension of SQL.
+ </PARA>
+
+ <REFSECT2 ID="R2-SQL-CREATEOPERATOR-4">
+ <REFSECT2INFO>
+ <DATE>1998-04-15</DATE>
+ </REFSECT2INFO>
+ <TITLE>
+ SQL92
+ </TITLE>
+ <PARA>
+ There is no CREATE OPERATOR statement on SQL92.
+ </PARA>
+ </refsect2>
+ </refsect1>
+</REFENTRY>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+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:
+-->