Skip to content

Commit 09c1c6a

Browse files
committed
Support INCLUDE'd columns in SP-GiST.
Not much to say here: does what it says on the tin. We steal a previously-always-zero bit from the nextOffset field of leaf index tuples in order to track whether there is a nulls bitmap. Otherwise it works about like included columns in other index types. Pavel Borisov, reviewed by Andrey Borodin and Anastasia Lubennikova, and rather heavily editorialized on by me Discussion: https://postgr.es/m/CALT9ZEFi-vMp4faht9f9Junb1nO3NOSjhpxTmbm1UGLMsLqiEQ@mail.gmail.com
1 parent 49f49de commit 09c1c6a

21 files changed

+631
-233
lines changed

doc/src/sgml/indices.sgml

+7-5
Original file line numberDiff line numberDiff line change
@@ -409,9 +409,11 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
409409
</para>
410410

411411
<para>
412-
Currently, only the B-tree, GiST, GIN, and BRIN
413-
index types support multicolumn
414-
indexes. Up to 32 columns can be specified. (This limit can be
412+
Currently, only the B-tree, GiST, GIN, and BRIN index types support
413+
multiple-key-column indexes. Whether there can be multiple key
414+
columns is independent of whether <literal>INCLUDE</literal> columns
415+
can be added to the index. Indexes can have up to 32 columns,
416+
including <literal>INCLUDE</literal> columns. (This limit can be
415417
altered when building <productname>PostgreSQL</productname>; see the
416418
file <filename>pg_config_manual.h</filename>.)
417419
</para>
@@ -1208,8 +1210,8 @@ CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y);
12081210
likely to not need to access the heap. If the heap tuple must be visited
12091211
anyway, it costs nothing more to get the column's value from there.
12101212
Other restrictions are that expressions are not currently supported as
1211-
included columns, and that only B-tree and GiST indexes currently support
1212-
included columns.
1213+
included columns, and that only B-tree, GiST and SP-GiST indexes currently
1214+
support included columns.
12131215
</para>
12141216

12151217
<para>

doc/src/sgml/ref/create_index.sgml

+6-3
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class=
187187
</para>
188188

189189
<para>
190-
Currently, the B-tree and the GiST index access methods support this
191-
feature. In B-tree and the GiST indexes, the values of columns listed
190+
Currently, the B-tree, GiST and SP-GiST index access methods support
191+
this feature. In these indexes, the values of columns listed
192192
in the <literal>INCLUDE</literal> clause are included in leaf tuples
193193
which correspond to heap tuples, but are not included in upper-level
194194
index entries used for tree navigation.
@@ -695,7 +695,10 @@ Indexes:
695695

696696
<para>
697697
Currently, only the B-tree, GiST, GIN, and BRIN index methods support
698-
multicolumn indexes. Up to 32 fields can be specified by default.
698+
multiple-key-column indexes. Whether there can be multiple key
699+
columns is independent of whether <literal>INCLUDE</literal> columns
700+
can be added to the index. Indexes can have up to 32 columns,
701+
including <literal>INCLUDE</literal> columns.
699702
(This limit can be altered when building
700703
<productname>PostgreSQL</productname>.) Only B-tree currently
701704
supports unique indexes.

doc/src/sgml/spgist.sgml

+8
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,14 @@
216216
inner tuples that are passed through to reach the leaf level.
217217
</para>
218218

219+
<para>
220+
When an <acronym>SP-GiST</acronym> index is created with
221+
<literal>INCLUDE</literal> columns, the values of those columns are also
222+
stored in leaf tuples. The <literal>INCLUDE</literal> columns are of no
223+
concern to the <acronym>SP-GiST</acronym> operator class, so they are
224+
not discussed further here.
225+
</para>
226+
219227
<para>
220228
Inner tuples are more complex, since they are branching points in the
221229
search tree. Each inner tuple contains a set of one or more

doc/src/sgml/xindex.sgml

+6-2
Original file line numberDiff line numberDiff line change
@@ -1426,11 +1426,15 @@ CREATE OPERATOR CLASS polygon_ops
14261426
STORAGE box;
14271427
</programlisting>
14281428

1429-
At present, only the GiST, GIN and BRIN index methods support a
1429+
At present, only the GiST, SP-GiST, GIN and BRIN index methods support a
14301430
<literal>STORAGE</literal> type that's different from the column data type.
14311431
The GiST <function>compress</function> and <function>decompress</function> support
14321432
routines must deal with data-type conversion when <literal>STORAGE</literal>
1433-
is used. In GIN, the <literal>STORAGE</literal> type identifies the type of
1433+
is used. SP-GiST likewise requires a <function>compress</function>
1434+
support function to convert to the storage type, when that is different;
1435+
if an SP-GiST opclass also supports retrieving data, the reverse
1436+
conversion must be handled by the <function>consistent</function> function.
1437+
In GIN, the <literal>STORAGE</literal> type identifies the type of
14341438
the <quote>key</quote> values, which normally is different from the type
14351439
of the indexed column &mdash; for example, an operator class for
14361440
integer-array columns might have keys that are just integers. The

src/backend/access/common/indextuple.c

+24-9
Original file line numberDiff line numberDiff line change
@@ -446,22 +446,37 @@ void
446446
index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,
447447
Datum *values, bool *isnull)
448448
{
449-
int hasnulls = IndexTupleHasNulls(tup);
450-
int natts = tupleDescriptor->natts; /* number of atts to extract */
451-
int attnum;
452449
char *tp; /* ptr to tuple data */
453-
int off; /* offset in tuple data */
454450
bits8 *bp; /* ptr to null bitmap in tuple */
455-
bool slow = false; /* can we use/set attcacheoff? */
456-
457-
/* Assert to protect callers who allocate fixed-size arrays */
458-
Assert(natts <= INDEX_MAX_KEYS);
459451

460452
/* XXX "knows" t_bits are just after fixed tuple header! */
461453
bp = (bits8 *) ((char *) tup + sizeof(IndexTupleData));
462454

463455
tp = (char *) tup + IndexInfoFindDataOffset(tup->t_info);
464-
off = 0;
456+
457+
index_deform_tuple_internal(tupleDescriptor, values, isnull,
458+
tp, bp, IndexTupleHasNulls(tup));
459+
}
460+
461+
/*
462+
* Convert an index tuple into Datum/isnull arrays,
463+
* without assuming any specific layout of the index tuple header.
464+
*
465+
* Caller must supply pointer to data area, pointer to nulls bitmap
466+
* (which can be NULL if !hasnulls), and hasnulls flag.
467+
*/
468+
void
469+
index_deform_tuple_internal(TupleDesc tupleDescriptor,
470+
Datum *values, bool *isnull,
471+
char *tp, bits8 *bp, int hasnulls)
472+
{
473+
int natts = tupleDescriptor->natts; /* number of atts to extract */
474+
int attnum;
475+
int off = 0; /* offset in tuple data */
476+
bool slow = false; /* can we use/set attcacheoff? */
477+
478+
/* Assert to protect callers who allocate fixed-size arrays */
479+
Assert(natts <= INDEX_MAX_KEYS);
465480

466481
for (attnum = 0; attnum < natts; attnum++)
467482
{

src/backend/access/spgist/README

+15-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ list and there is no free space on page, then SP-GiST creates a new inner
5656
tuple and distributes leaf tuples into a set of lists on, perhaps, several
5757
pages.
5858

59-
Inner tuple consists of:
59+
An inner tuple consists of:
6060

6161
optional prefix value - all successors must be consistent with it.
6262
Example:
@@ -67,14 +67,26 @@ Inner tuple consists of:
6767
list of nodes, where node is a (label, pointer) pair.
6868
Example of a label: a single character for radix tree
6969

70-
Leaf tuple consists of:
70+
A leaf tuple consists of:
7171

7272
a leaf value
7373
Example:
7474
radix tree - the rest of string (postfix)
7575
quad and k-d tree - the point itself
7676

77-
ItemPointer to the heap
77+
ItemPointer to the corresponding heap tuple
78+
nextOffset number of next leaf tuple in a chain on a leaf page
79+
80+
optional nulls bitmask
81+
optional INCLUDE-column values
82+
83+
For compatibility with pre-v14 indexes, a leaf tuple has a nulls bitmask
84+
only if there are null values (among the leaf value and the INCLUDE values)
85+
*and* there is at least one INCLUDE column. The null-ness of the leaf
86+
value can be inferred from whether the tuple is on a "nulls page" (see below)
87+
so it is not necessary to represent it explicitly. But we include it anyway
88+
in a bitmask used with INCLUDE values, so that standard tuple deconstruction
89+
code can be used.
7890

7991

8092
NULLS HANDLING

0 commit comments

Comments
 (0)