From 2744abb736fefe89e3ce8d23024a6ab0d343bdf5 Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Tue, 21 Oct 2003 23:28:42 +0000 Subject: [PATCH] Ooops, missed updating this part of the complex-datatype example. --- doc/src/sgml/xindex.sgml | 80 +++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml index 4d99f5dea0c..aa9e39794e8 100644 --- a/doc/src/sgml/xindex.sgml +++ b/doc/src/sgml/xindex.sgml @@ -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"> @@ -408,7 +408,12 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.32 2003/08/31 17:32:21 pete <para> 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 choose the name <literal>complex_abs_ops</literal>. First, we need 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> - 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> -#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y) +#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y) -bool -complex_abs_eq(Complex *a, Complex *b) +static int +complex_abs_cmp_internal(Complex *a, Complex *b) { - double amag = Mag(a), bmag = Mag(b); - return (amag == bmag); + double amag = Mag(a), + bmag = Mag(b); + + if (amag < bmag) + return -1; + if (amag > bmag) + return 1; + return 0; } </programlisting> - The other four operators are very similar. You can find their code - in <filename>src/tutorial/complex.c</filename> and - <filename>src/tutorial/complex.sql</filename> in the source - distribution. + + Now the less-than function looks like + +<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> - Now declare the functions and the operators based on the functions: + Next we declare the functions and the operators based on the functions + to SQL: + <programlisting> -CREATE FUNCTION complex_abs_eq(complex, complex) RETURNS boolean - AS '<replaceable>filename</replaceable>', 'complex_abs_eq' - LANGUAGE C; - -CREATE OPERATOR = ( - leftarg = complex, - rightarg = complex, - procedure = complex_abs_eq, - restrict = eqsel, - join = eqjoinsel +CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool + AS '<replaceable>filename</replaceable>', 'complex_abs_lt' + LANGUAGE C IMMUTABLE STRICT; + +CREATE OPERATOR < ( + leftarg = complex, rightarg = complex, procedure = complex_abs_lt, + commutator = > , negator = >= , + restrict = scalarltsel, join = scalarltjoinsel ); </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 use of the index. Note that the less-than, equal, and greater-than cases should use different selectivity functions. @@ -518,7 +548,7 @@ CREATE OPERATOR = ( CREATE FUNCTION complex_abs_cmp(complex, complex) RETURNS integer AS '<replaceable>filename</replaceable>' - LANGUAGE C; + LANGUAGE C IMMUTABLE STRICT; </programlisting> </para> -- GitLab