mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Ooops, missed updating this part of the complex-datatype example.
This commit is contained in:
parent
6fbb14a174
commit
2744abb736
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.32 2003/08/31 17:32:21 petere Exp $
|
$Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.33 2003/10/21 23:28:42 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<sect1 id="xindex">
|
<sect1 id="xindex">
|
||||||
@ -408,7 +408,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.32 2003/08/31 17:32:21 pete
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
Now that we have seen the ideas, here is the promised example of
|
Now that we have seen the ideas, here is the promised example of
|
||||||
creating a new operator class. The operator class encapsulates
|
creating a new operator class.
|
||||||
|
(You can find a working copy of this example in
|
||||||
|
<filename>src/tutorial/complex.c</filename> and
|
||||||
|
<filename>src/tutorial/complex.sql</filename> in the source
|
||||||
|
distribution.)
|
||||||
|
The operator class encapsulates
|
||||||
operators that sort complex numbers in absolute value order, so we
|
operators that sort complex numbers in absolute value order, so we
|
||||||
choose the name <literal>complex_abs_ops</literal>. First, we need
|
choose the name <literal>complex_abs_ops</literal>. First, we need
|
||||||
a set of operators. The procedure for defining operators was
|
a set of operators. The procedure for defining operators was
|
||||||
@ -425,40 +430,65 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.32 2003/08/31 17:32:21 pete
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The C code for the equality operator look like this:
|
The least error-prone way to define a related set of comparison operators
|
||||||
|
is to write the btree comparison support function first, and then write the
|
||||||
|
other functions as one-line wrappers around the support function. This
|
||||||
|
reduces the odds of getting inconsistent results for corner cases.
|
||||||
|
Following this approach, we first write
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
|
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
|
||||||
|
|
||||||
bool
|
static int
|
||||||
complex_abs_eq(Complex *a, Complex *b)
|
complex_abs_cmp_internal(Complex *a, Complex *b)
|
||||||
{
|
{
|
||||||
double amag = Mag(a), bmag = Mag(b);
|
double amag = Mag(a),
|
||||||
return (amag == bmag);
|
bmag = Mag(b);
|
||||||
|
|
||||||
|
if (amag < bmag)
|
||||||
|
return -1;
|
||||||
|
if (amag > bmag)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
The other four operators are very similar. You can find their code
|
|
||||||
in <filename>src/tutorial/complex.c</filename> and
|
Now the less-than function looks like
|
||||||
<filename>src/tutorial/complex.sql</filename> in the source
|
|
||||||
distribution.
|
<programlisting>
|
||||||
|
PG_FUNCTION_INFO_V1(complex_abs_lt);
|
||||||
|
|
||||||
|
Datum
|
||||||
|
complex_abs_lt(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
Complex *a = (Complex *) PG_GETARG_POINTER(0);
|
||||||
|
Complex *b = (Complex *) PG_GETARG_POINTER(1);
|
||||||
|
|
||||||
|
PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
The other four functions differ only in how they compare the internal
|
||||||
|
function's result to zero.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Now declare the functions and the operators based on the functions:
|
Next we declare the functions and the operators based on the functions
|
||||||
<programlisting>
|
to SQL:
|
||||||
CREATE FUNCTION complex_abs_eq(complex, complex) RETURNS boolean
|
|
||||||
AS '<replaceable>filename</replaceable>', 'complex_abs_eq'
|
|
||||||
LANGUAGE C;
|
|
||||||
|
|
||||||
CREATE OPERATOR = (
|
<programlisting>
|
||||||
leftarg = complex,
|
CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool
|
||||||
rightarg = complex,
|
AS '<replaceable>filename</replaceable>', 'complex_abs_lt'
|
||||||
procedure = complex_abs_eq,
|
LANGUAGE C IMMUTABLE STRICT;
|
||||||
restrict = eqsel,
|
|
||||||
join = eqjoinsel
|
CREATE OPERATOR < (
|
||||||
|
leftarg = complex, rightarg = complex, procedure = complex_abs_lt,
|
||||||
|
commutator = > , negator = >= ,
|
||||||
|
restrict = scalarltsel, join = scalarltjoinsel
|
||||||
);
|
);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
It is important to specify the restriction and join selectivity
|
It is important to specify the correct commutator and negator operators,
|
||||||
|
as well as suitable restriction and join selectivity
|
||||||
functions, otherwise the optimizer will be unable to make effective
|
functions, otherwise the optimizer will be unable to make effective
|
||||||
use of the index. Note that the less-than, equal, and
|
use of the index. Note that the less-than, equal, and
|
||||||
greater-than cases should use different selectivity functions.
|
greater-than cases should use different selectivity functions.
|
||||||
@ -518,7 +548,7 @@ CREATE OPERATOR = (
|
|||||||
CREATE FUNCTION complex_abs_cmp(complex, complex)
|
CREATE FUNCTION complex_abs_cmp(complex, complex)
|
||||||
RETURNS integer
|
RETURNS integer
|
||||||
AS '<replaceable>filename</replaceable>'
|
AS '<replaceable>filename</replaceable>'
|
||||||
LANGUAGE C;
|
LANGUAGE C IMMUTABLE STRICT;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user