6464
6565 <table id="spgist-builtin-opclasses-table">
6666 <title>Built-in <acronym>SP-GiST</acronym> Operator Classes</title>
67- <tgroup cols="3 ">
67+ <tgroup cols="4 ">
6868 <thead>
6969 <row>
7070 <entry>Name</entry>
7171 <entry>Indexed Data Type</entry>
7272 <entry>Indexable Operators</entry>
73+ <entry>Ordering Operators</entry>
7374 </row>
7475 </thead>
7576 <tbody>
8485 <literal>>^</literal>
8586 <literal>~=</literal>
8687 </entry>
88+ <entry>
89+ <literal><-></literal>
90+ </entry>
8791 </row>
8892 <row>
8993 <entry><literal>quad_point_ops</literal></entry>
96100 <literal>>^</literal>
97101 <literal>~=</literal>
98102 </entry>
103+ <entry>
104+ <literal><-></literal>
105+ </entry>
99106 </row>
100107 <row>
101108 <entry><literal>range_ops</literal></entry>
111118 <literal>>></literal>
112119 <literal>@></literal>
113120 </entry>
121+ <entry>
122+ </entry>
114123 </row>
115124 <row>
116125 <entry><literal>box_ops</literal></entry>
129138 <literal>|>></literal>
130139 <literal>|&></literal>
131140 </entry>
141+ <entry>
142+ </entry>
132143 </row>
133144 <row>
134145 <entry><literal>poly_ops</literal></entry>
147158 <literal>|>></literal>
148159 <literal>|&></literal>
149160 </entry>
161+ <entry>
162+ <literal><-></literal>
163+ </entry>
150164 </row>
151165 <row>
152166 <entry><literal>text_ops</literal></entry>
163177 <literal>~>~</literal>
164178 <literal>^@</literal>
165179 </entry>
180+ <entry>
181+ </entry>
166182 </row>
167183 <row>
168184 <entry><literal>inet_ops</literal></entry>
180196 <literal><=</literal>
181197 <literal>=</literal>
182198 </entry>
199+ <entry>
200+ </entry>
183201 </row>
184202 </tbody>
185203 </tgroup>
191209 supports the same operators but uses a different index data structure which
192210 may offer better performance in some applications.
193211 </para>
212+ <para>
213+ The <literal>quad_point_ops</literal>, <literal>kd_point_ops</literal> and
214+ <literal>poly_ops</literal> operator classes support the <literal><-></literal>
215+ ordering operator, which enables the k-nearest neighbor (<literal>k-NN</literal>)
216+ search over indexed point or polygon datasets.
217+ </para>
194218
195219</sect1>
196220
@@ -630,7 +654,10 @@ CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ...
630654typedef struct spgInnerConsistentIn
631655{
632656 ScanKey scankeys; /* array of operators and comparison values */
633- int nkeys; /* length of array */
657+ ScanKey orderbys; /* array of ordering operators and comparison
658+ * values */
659+ int nkeys; /* length of scankeys array */
660+ int norderbys; /* length of orderbys array */
634661
635662 Datum reconstructedValue; /* value reconstructed at parent */
636663 void *traversalValue; /* opclass-specific traverse value */
@@ -653,6 +680,7 @@ typedef struct spgInnerConsistentOut
653680 int *levelAdds; /* increment level by this much for each */
654681 Datum *reconstructedValues; /* associated reconstructed values */
655682 void **traversalValues; /* opclass-specific traverse values */
683+ double **distances; /* associated distances */
656684} spgInnerConsistentOut;
657685</programlisting>
658686
@@ -667,6 +695,8 @@ typedef struct spgInnerConsistentOut
667695 In particular it is not necessary to check <structfield>sk_flags</structfield> to
668696 see if the comparison value is NULL, because the SP-GiST core code
669697 will filter out such conditions.
698+ The array <structfield>orderbys</structfield>, of length <structfield>norderbys</structfield>,
699+ describes ordering operators (if any) in the same manner.
670700 <structfield>reconstructedValue</structfield> is the value reconstructed for the
671701 parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
672702 <function>inner_consistent</function> function did not provide a value at the
@@ -709,6 +739,10 @@ typedef struct spgInnerConsistentOut
709739 of <structname>spgConfigOut</structname>.<structfield>leafType</structfield> type
710740 reconstructed for each child node to be visited; otherwise, leave
711741 <structfield>reconstructedValues</structfield> as NULL.
742+ If ordered search is performed, set <structfield>distances</structfield>
743+ to an array of distance values according to <structfield>orderbys</structfield>
744+ array (nodes with lowest distances will be processed first). Leave it
745+ NULL otherwise.
712746 If it is desired to pass down additional out-of-band information
713747 (<quote>traverse values</quote>) to lower levels of the tree search,
714748 set <structfield>traversalValues</structfield> to an array of the appropriate
@@ -717,6 +751,7 @@ typedef struct spgInnerConsistentOut
717751 Note that the <function>inner_consistent</function> function is
718752 responsible for palloc'ing the
719753 <structfield>nodeNumbers</structfield>, <structfield>levelAdds</structfield>,
754+ <structfield>distances</structfield>,
720755 <structfield>reconstructedValues</structfield>, and
721756 <structfield>traversalValues</structfield> arrays in the current memory context.
722757 However, any output traverse values pointed to by
@@ -747,7 +782,10 @@ CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ...
747782typedef struct spgLeafConsistentIn
748783{
749784 ScanKey scankeys; /* array of operators and comparison values */
750- int nkeys; /* length of array */
785+ ScanKey orderbys; /* array of ordering operators and comparison
786+ * values */
787+ int nkeys; /* length of scankeys array */
788+ int norderbys; /* length of orderbys array */
751789
752790 Datum reconstructedValue; /* value reconstructed at parent */
753791 void *traversalValue; /* opclass-specific traverse value */
@@ -759,8 +797,10 @@ typedef struct spgLeafConsistentIn
759797
760798typedef struct spgLeafConsistentOut
761799{
762- Datum leafValue; /* reconstructed original data, if any */
763- bool recheck; /* set true if operator must be rechecked */
800+ Datum leafValue; /* reconstructed original data, if any */
801+ bool recheck; /* set true if operator must be rechecked */
802+ bool recheckDistances; /* set true if distances must be rechecked */
803+ double *distances; /* associated distances */
764804} spgLeafConsistentOut;
765805</programlisting>
766806
@@ -775,6 +815,8 @@ typedef struct spgLeafConsistentOut
775815 In particular it is not necessary to check <structfield>sk_flags</structfield> to
776816 see if the comparison value is NULL, because the SP-GiST core code
777817 will filter out such conditions.
818+ The array <structfield>orderbys</structfield>, of length <structfield>norderbys</structfield>,
819+ describes the ordering operators in the same manner.
778820 <structfield>reconstructedValue</structfield> is the value reconstructed for the
779821 parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
780822 <function>inner_consistent</function> function did not provide a value at the
@@ -803,6 +845,12 @@ typedef struct spgLeafConsistentOut
803845 <structfield>recheck</structfield> may be set to <literal>true</literal> if the match
804846 is uncertain and so the operator(s) must be re-applied to the actual
805847 heap tuple to verify the match.
848+ If ordered search is performed, set <structfield>distances</structfield>
849+ to an array of distance values according to <structfield>orderbys</structfield>
850+ array. Leave it NULL otherwise. If at least one of returned distances
851+ is not exact, set <structfield>recheckDistances</structfield> to true.
852+ In this case, the executor will calculate the exact distances after
853+ fetching the tuple from the heap, and will reorder the tuples if needed.
806854 </para>
807855 </listitem>
808856 </varlistentry>
0 commit comments