114
114
</row>
115
115
<row>
116
116
<entry><literal>box_ops</></entry>
117
- <entry>box</entry>
117
+ <entry><type> box</> </entry>
118
118
<entry>
119
119
<literal><<</>
120
120
<literal>&<</>
183
183
Inner tuples are more complex, since they are branching points in the
184
184
search tree. Each inner tuple contains a set of one or more
185
185
<firstterm>nodes</>, which represent groups of similar leaf values.
186
- A node contains a downlink that leads to either another, lower-level inner
187
- tuple, or a short list of leaf tuples that all lie on the same index page.
188
- Each node has a <firstterm>label</> that describes it; for example,
186
+ A node contains a downlink that leads either to another, lower-level inner
187
+ tuple, or to a short list of leaf tuples that all lie on the same index page.
188
+ Each node normally has a <firstterm>label</> that describes it; for example,
189
189
in a radix tree the node label could be the next character of the string
190
- value. Optionally, an inner tuple can have a <firstterm>prefix</> value
190
+ value. (Alternatively, an operator class can omit the node labels, if it
191
+ works with a fixed set of nodes for all inner tuples;
192
+ see <xref linkend="spgist-null-labels">.)
193
+ Optionally, an inner tuple can have a <firstterm>prefix</> value
191
194
that describes all its members. In a radix tree this could be the common
192
195
prefix of the represented strings. The prefix value is not necessarily
193
196
really a prefix, but can be any data needed by the operator class;
202
205
tuple, so the <acronym>SP-GiST</acronym> core provides the possibility for
203
206
operator classes to manage level counting while descending the tree.
204
207
There is also support for incrementally reconstructing the represented
205
- value when that is needed.
208
+ value when that is needed, and for passing down additional data (called
209
+ <firstterm>traverse values</>) during a tree descent.
206
210
</para>
207
211
208
212
<note>
@@ -343,10 +347,13 @@ typedef struct spgChooseOut
343
347
} addNode;
344
348
struct /* results for spgSplitTuple */
345
349
{
346
- /* Info to form new inner tuple with one node */
350
+ /* Info to form new upper-level inner tuple with one child tuple */
347
351
bool prefixHasPrefix; /* tuple should have a prefix? */
348
352
Datum prefixPrefixDatum; /* if so, its value */
349
- Datum nodeLabel; /* node's label */
353
+ int prefixNNodes; /* number of nodes */
354
+ Datum *prefixNodeLabels; /* their labels (or NULL for
355
+ * no labels) */
356
+ int childNodeN; /* which node gets child tuple */
350
357
351
358
/* Info to form new lower-level inner tuple with all old nodes */
352
359
bool postfixHasPrefix; /* tuple should have a prefix? */
@@ -416,29 +423,33 @@ typedef struct spgChooseOut
416
423
set <structfield>resultType</> to <literal>spgSplitTuple</>.
417
424
This action moves all the existing nodes into a new lower-level
418
425
inner tuple, and replaces the existing inner tuple with a tuple
419
- having a single node that links to the new lower-level inner tuple.
426
+ having a single downlink pointing to the new lower-level inner tuple.
420
427
Set <structfield>prefixHasPrefix</> to indicate whether the new
421
428
upper tuple should have a prefix, and if so set
422
429
<structfield>prefixPrefixDatum</> to the prefix value. This new
423
430
prefix value must be sufficiently less restrictive than the original
424
- to accept the new value to be indexed, and it should be no longer
425
- than the original prefix.
426
- Set <structfield>nodeLabel</> to the label to be used for the
427
- node that will point to the new lower-level inner tuple.
431
+ to accept the new value to be indexed.
432
+ Set <structfield>prefixNNodes</> to the number of nodes needed in the
433
+ new tuple, and set <structfield>prefixNodeLabels</> to a palloc'd array
434
+ holding their labels, or to NULL if node labels are not required.
435
+ Note that the total size of the new upper tuple must be no more
436
+ than the total size of the tuple it is replacing; this constrains
437
+ the lengths of the new prefix and new labels.
438
+ Set <structfield>childNodeN</> to the index (from zero) of the node
439
+ that will downlink to the new lower-level inner tuple.
428
440
Set <structfield>postfixHasPrefix</> to indicate whether the new
429
441
lower-level inner tuple should have a prefix, and if so set
430
442
<structfield>postfixPrefixDatum</> to the prefix value. The
431
- combination of these two prefixes and the additional label must
432
- have the same meaning as the original prefix, because there is
433
- no opportunity to alter the node labels that are moved to the new
434
- lower-level tuple, nor to change any child index entries.
443
+ combination of these two prefixes and the downlink node's label
444
+ (if any) must have the same meaning as the original prefix, because
445
+ there is no opportunity to alter the node labels that are moved to
446
+ the new lower-level tuple, nor to change any child index entries.
435
447
After the node has been split, the <function>choose</function>
436
448
function will be called again with the replacement inner tuple.
437
- That call will usually result in an <literal>spgAddNode</> result,
438
- since presumably the node label added in the split step will not
439
- match the new value; so after that, there will be a third call
440
- that finally returns <literal>spgMatchNode</> and allows the
441
- insertion to descend to the leaf level.
449
+ That call may return an <literal>spgAddNode</> result, if no suitable
450
+ node was created by the <literal>spgSplitTuple</> action. Eventually
451
+ <function>choose</function> must return <literal>spgMatchNode</> to
452
+ allow the insertion to descend to the next level.
442
453
</para>
443
454
</listitem>
444
455
</varlistentry>
@@ -492,9 +503,8 @@ typedef struct spgPickSplitOut
492
503
<structfield>prefixDatum</> to the prefix value.
493
504
Set <structfield>nNodes</> to indicate the number of nodes that
494
505
the new inner tuple will contain, and
495
- set <structfield>nodeLabels</> to an array of their label values.
496
- (If the nodes do not require labels, set <structfield>nodeLabels</>
497
- to NULL; see <xref linkend="spgist-null-labels"> for details.)
506
+ set <structfield>nodeLabels</> to an array of their label values,
507
+ or to NULL if node labels are not required.
498
508
Set <structfield>mapTuplesToNodes</> to an array that gives the index
499
509
(from zero) of the node that each leaf tuple should be assigned to.
500
510
Set <structfield>leafTupleDatums</> to an array of the values to
@@ -561,7 +571,7 @@ typedef struct spgInnerConsistentIn
561
571
562
572
Datum reconstructedValue; /* value reconstructed at parent */
563
573
void *traversalValue; /* opclass-specific traverse value */
564
- MemoryContext traversalMemoryContext;
574
+ MemoryContext traversalMemoryContext; /* put new traverse values here */
565
575
int level; /* current level (counting from zero) */
566
576
bool returnData; /* original data must be returned? */
567
577
@@ -580,7 +590,6 @@ typedef struct spgInnerConsistentOut
580
590
int *levelAdds; /* increment level by this much for each */
581
591
Datum *reconstructedValues; /* associated reconstructed values */
582
592
void **traversalValues; /* opclass-specific traverse values */
583
-
584
593
} spgInnerConsistentOut;
585
594
</programlisting>
586
595
@@ -599,6 +608,11 @@ typedef struct spgInnerConsistentOut
599
608
parent tuple; it is <literal>(Datum) 0</> at the root level or if the
600
609
<function>inner_consistent</> function did not provide a value at the
601
610
parent level.
611
+ <structfield>traversalValue</> is a pointer to any traverse data
612
+ passed down from the previous call of <function>inner_consistent</>
613
+ on the parent index tuple, or NULL at the root level.
614
+ <structfield>traversalMemoryContext</> is the memory context in which
615
+ to store output traverse values (see below).
602
616
<structfield>level</> is the current inner tuple's level, starting at
603
617
zero for the root level.
604
618
<structfield>returnData</> is <literal>true</> if reconstructed data is
@@ -615,9 +629,6 @@ typedef struct spgInnerConsistentOut
615
629
inner tuple, and
616
630
<structfield>nodeLabels</> is an array of their label values, or
617
631
NULL if the nodes do not have labels.
618
- <structfield>traversalValue</> is a pointer to data that
619
- <function>inner_consistent</> gets when called on child nodes from an
620
- outer call of <function>inner_consistent</> on parent nodes.
621
632
</para>
622
633
623
634
<para>
@@ -633,17 +644,19 @@ typedef struct spgInnerConsistentOut
633
644
<structfield>reconstructedValues</> to an array of the values
634
645
reconstructed for each child node to be visited; otherwise, leave
635
646
<structfield>reconstructedValues</> as NULL.
647
+ If it is desired to pass down additional out-of-band information
648
+ (<quote>traverse values</>) to lower levels of the tree search,
649
+ set <structfield>traversalValues</> to an array of the appropriate
650
+ traverse values, one for each child node to be visited; otherwise,
651
+ leave <structfield>traversalValues</> as NULL.
636
652
Note that the <function>inner_consistent</> function is
637
653
responsible for palloc'ing the
638
- <structfield>nodeNumbers</>, <structfield>levelAdds</> and
639
- <structfield>reconstructedValues</> arrays.
640
- Sometimes accumulating some information is needed, while
641
- descending from parent to child node was happened. In this case
642
- <structfield>traversalValues</> array keeps pointers to
643
- specific data you need to accumulate for every child node.
644
- Memory for <structfield>traversalValues</> should be allocated in
645
- the default context, but each element of it should be allocated in
646
- <structfield>traversalMemoryContext</>.
654
+ <structfield>nodeNumbers</>, <structfield>levelAdds</>,
655
+ <structfield>reconstructedValues</>, and
656
+ <structfield>traversalValues</> arrays in the current memory context.
657
+ However, any output traverse values pointed to by
658
+ the <structfield>traversalValues</> array should be allocated
659
+ in <structfield>traversalMemoryContext</>.
647
660
</para>
648
661
</listitem>
649
662
</varlistentry>
@@ -670,8 +683,8 @@ typedef struct spgLeafConsistentIn
670
683
ScanKey scankeys; /* array of operators and comparison values */
671
684
int nkeys; /* length of array */
672
685
673
- void *traversalValue; /* opclass-specific traverse value */
674
686
Datum reconstructedValue; /* value reconstructed at parent */
687
+ void *traversalValue; /* opclass-specific traverse value */
675
688
int level; /* current level (counting from zero) */
676
689
bool returnData; /* original data must be returned? */
677
690
@@ -700,6 +713,9 @@ typedef struct spgLeafConsisten
F438
tOut
700
713
parent tuple; it is <literal>(Datum) 0</> at the root level or if the
701
714
<function>inner_consistent</> function did not provide a value at the
702
715
parent level.
716
+ <structfield>traversalValue</> is a pointer to any traverse data
717
+ passed down from the previous call of <function>inner_consistent</>
718
+ on the parent index tuple, or NULL at the root level.
703
719
<structfield>level</> is the current leaf tuple's level, starting at
704
720
zero for the root level.
705
721
<structfield>returnData</> is <literal>true</> if reconstructed data is
@@ -797,7 +813,10 @@ typedef struct spgLeafConsistentOut
797
813
point. In such a case the code typically works with the nodes by
798
814
number, and there is no need for explicit node labels. To suppress
799
815
node labels (and thereby save some space), the <function>picksplit</>
800
- function can return NULL for the <structfield>nodeLabels</> array.
816
+ function can return NULL for the <structfield>nodeLabels</> array,
817
+ and likewise the <function>choose</> function can return NULL for
818
+ the <structfield>prefixNodeLabels</> array during
819
+ a <literal>spgSplitTuple</> action.
801
820
This will in turn result in <structfield>nodeLabels</> being NULL during
802
821
subsequent calls to <function>choose</> and <function>inner_consistent</>.
803
822
In principle, node labels could be used for some inner tuples and omitted
@@ -807,10 +826,7 @@ typedef struct spgLeafConsistentOut
807
826
<para>
808
827
When working with an inner tuple having unlabeled nodes, it is an error
809
828
for <function>choose</> to return <literal>spgAddNode</>, since the set
810
- of nodes is supposed to be fixed in such cases. Also, there is no
811
- provision for generating an unlabeled node in <literal>spgSplitTuple</>
812
- actions, since it is expected that an <literal>spgAddNode</> action will
813
- be needed as well.
829
+ of nodes is supposed to be fixed in such cases.
814
830
</para>
815
831
</sect2>
816
832
@@ -859,11 +875,10 @@ typedef struct spgLeafConsistentOut
859
875
860
876
<para>
861
877
The <productname>PostgreSQL</productname> source distribution includes
862
- several examples of index operator classes for
863
- <acronym>SP-GiST</acronym>. The core system currently provides radix
864
- trees over text columns and two types of trees over points: quad-tree and
865
- k-d tree. Look into <filename>src/backend/access/spgist/</> to see the
866
- code.
878
+ several examples of index operator classes for <acronym>SP-GiST</acronym>,
879
+ as described in <xref linkend="spgist-builtin-opclasses-table">. Look
880
+ into <filename>src/backend/access/spgist/</>
881
+ and <filename>src/backend/utils/adt/</> to see the code.
867
882
</para>
868
883
869
884
</sect1>
0 commit comments