added,
set <structfield>resultType</structfield> to <literal>spgAddNode</literal>.
Set <structfield>nodeLabel</structfield> to the label to be used for the new
node, and set <structfield>nodeN</structfield> to the index (from zero) at which
to insert the node in the node array.
After the node has been added, the <function>choose</function>
function will be called again with the modified inner tuple;
that call should result in an <literal>spgMatchNode</literal> result.
</para>
<para>
If the new value is inconsistent with the tuple prefix,
set <structfield>resultType</structfield> to <literal>spgSplitTuple</literal>.
This action moves all the existing nodes into a new lower-level
inner tuple, and replaces the existing inner tuple with a tuple
having a single downlink pointing to the new lower-level inner tuple.
Set <structfield>prefixHasPrefix</structfield> to indicate whether the new
upper tuple should have a prefix, and if so set
<structfield>prefixPrefixDatum</structfield> to the prefix value. This new
prefix value must be sufficiently less restrictive than the original
to accept the new value to be indexed.
Set <structfield>prefixNNodes</structfield> to the number of nodes needed in the
new tuple, and set <structfield>prefixNodeLabels</structfield> to a palloc'd array
holding their labels, or to NULL if node labels are not required.
Note that the total size of the new upper tuple must be no more
than the total size of the tuple it is replacing; this constrains
the lengths of the new prefix and new labels.
Set <structfield>childNodeN</structfield> to the index (from zero) of the node
that will downlink to the new lower-level inner tuple.
Set <structfield>postfixHasPrefix</structfield> to indicate whether the new
lower-level inner tuple should have a prefix, and if so set
<structfield>postfixPrefixDatum</structfield> to the prefix value. The
combination of these two prefixes and the downlink node's label
(if any) must have the same meaning as the original prefix, because
there is no opportunity to alter the node labels that are moved to
the new lower-level tuple, nor to change any child index entries.
After the node has been split, the <function>choose</function>
function will be called again with the replacement inner tuple.
That call may return an <literal>spgAddNode</literal> result, if no suitable
node was created by the <literal>spgSplitTuple</literal> action. Eventually
<function>choose</function> must return <literal>spgMatchNode</literal> to
allow the insertion to descend to the next level.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><function>picksplit</function></term>
<listitem>
<para>
Decides how to create a new inner tuple over a set of leaf tuples.
</para>
<para>
The <acronym>SQL</acronym> declaration of the function must look like this:
<programlisting>
CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ...
</programlisting>
The first argument is a pointer to a <structname>spgPickSplitIn</structname>
C struct, containing input data for the function.
The second argument is a pointer to a <structname>spgPickSplitOut</structname>
C struct, which the function must fill with result data.
<programlisting>
typedef struct spgPickSplitIn
{
int nTuples; /* number of leaf tuples */
Datum *datums; /* their datums (array of length nTuples) */
int level; /* current level (counting from zero) */
} spgPickSplitIn;
typedef struct spgPickSplitOut
{
bool hasPrefix; /* new inner tuple should have a prefix? */
Datum prefixDatum; /* if so, its value */
int