Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9220362

Browse files
committed
Teach SP-GiST to do index-only scans.
Operator classes can specify whether or not they support this; this preserves the flexibility to use lossy representations within an index. In passing, move constant data about a given index into the rd_amcache cache area, instead of doing fresh lookups each time we start an index operation. This is mainly to try to make sure that spgcanreturn() has insignificant cost; I still don't have any proof that it matters for actual index accesses. Also, get rid of useless copying of FmgrInfo pointers; we can perfectly well use the relcache's versions in-place.
1 parent 3695a55 commit 9220362

File tree

10 files changed

+286
-172
lines changed

10 files changed

+286
-172
lines changed

doc/src/sgml/spgist.sgml

+15
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ typedef struct spgConfigOut
145145
{
146146
Oid prefixType; /* Data type of inner-tuple prefixes */
147147
Oid labelType; /* Data type of inner-tuple node labels */
148+
bool canReturnData; /* Opclass can reconstruct original data */
148149
bool longValuesOK; /* Opclass can cope with values > 1 page */
149150
} spgConfigOut;
150151
</programlisting>
@@ -159,6 +160,8 @@ typedef struct spgConfigOut
159160
<structfield>prefixType</> can be set to <literal>VOIDOID</>.
160161
Likewise, for operator classes that do not use node labels,
161162
<structfield>labelType</> can be set to <literal>VOIDOID</>.
163+
<structfield>canReturnData</> should be set true if the operator class
164+
is capable of reconstructing the originally-supplied index value.
162165
<structfield>longValuesOK</> should be set true only when the
163166
<structfield>attType</> is of variable length and the operator
164167
class is capable of segmenting long values by repeated suffixing
@@ -441,6 +444,7 @@ typedef struct spgInnerConsistentIn
441444

442445
Datum reconstructedValue; /* value reconstructed at parent */
443446
int level; /* current level (counting from zero) */
447+
bool returnData; /* original data must be returned? */
444448

445449
/* Data from current inner tuple */
446450
bool allTheSame; /* tuple is marked all-the-same? */
@@ -467,6 +471,9 @@ typedef struct spgInnerConsistentOut
467471
parent level.
468472
<structfield>level</> is the current inner tuple's level, starting at
469473
zero for the root level.
474+
<structfield>returnData</> is <literal>true</> if reconstructed data is
475+
required for this query; this will only be so if the
476+
<function>config</> function asserted <structfield>canReturnData</>.
470477
<structfield>allTheSame</> is true if the current inner tuple is
471478
marked <quote>all-the-same</>; in this case all the nodes have the
472479
same label (if any) and so either all or none of them match the query
@@ -525,12 +532,14 @@ typedef struct spgLeafConsistentIn
525532

526533
Datum reconstructedValue; /* value reconstructed at parent */
527534
int level; /* current level (counting from zero) */
535+
bool returnData; /* original data must be returned? */
528536

529537
Datum leafDatum; /* datum in leaf tuple */
530538
} spgLeafConsistentIn;
531539

532540
typedef struct spgLeafConsistentOut
533541
{
542+
Datum leafValue; /* reconstructed original data, if any */
534543
bool recheck; /* set true if operator must be rechecked */
535544
} spgLeafConsistentOut;
536545
</programlisting>
@@ -543,13 +552,19 @@ typedef struct spgLeafConsistentOut
543552
parent level.
544553
<structfield>level</> is the current leaf tuple's level, starting at
545554
zero for the root level.
555+
<structfield>returnData</> is <literal>true</> if reconstructed data is
556+
required for this query; this will only be so if the
557+
<function>config</> function asserted <structfield>canReturnData</>.
546558
<structfield>leafDatum</> is the key value stored in the current
547559
leaf tuple.
548560
</para>
549561

550562
<para>
551563
The function must return <literal>true</> if the leaf tuple matches the
552564
query, or <literal>false</> if not. In the <literal>true</> case,
565+
if <structfield>returnData</> is <literal>true</> then
566+
<structfield>leafValue</> must be set to the value originally supplied
567+
to be indexed for this leaf tuple. Also,
553568
<structfield>recheck</> may be set to <literal>true</> if the match
554569
is uncertain and so the operator must be re-applied to the actual heap
555570
tuple to verify the match.

src/backend/access/spgist/spgdoinsert.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "postgres.h"
1717

18+
#include "access/genam.h"
1819
#include "access/spgist_private.h"
1920
#include "miscadmin.h"
2021
#include "storage/bufmgr.h"
@@ -678,6 +679,7 @@ doPickSplit(Relation index, SpGistState *state,
678679
bool insertedNew = false;
679680
spgPickSplitIn in;
680681
spgPickSplitOut out;
682+
FmgrInfo *procinfo;
681683
bool includeNew;
682684
int i,
683685
max,
@@ -816,7 +818,8 @@ doPickSplit(Relation index, SpGistState *state,
816818
*/
817819
memset(&out, 0, sizeof(out));
818820

819-
FunctionCall2Coll(&state->picksplitFn,
821+
procinfo = index_getprocinfo(index, 1, SPGIST_PICKSPLIT_PROC);
822+
FunctionCall2Coll(procinfo,
820823
index->rd_indcollation[0],
821824
PointerGetDatum(&in),
822825
PointerGetDatum(&out));
@@ -1944,6 +1947,7 @@ spgdoinsert(Relation index, SpGistState *state,
19441947
SpGistInnerTuple innerTuple;
19451948
spgChooseIn in;
19461949
spgChooseOut out;
1950+
FmgrInfo *procinfo;
19471951

19481952
/*
19491953
* spgAddNode and spgSplitTuple cases will loop back to here to
@@ -1968,7 +1972,8 @@ spgdoinsert(Relation index, SpGistState *state,
19681972

19691973
memset(&out, 0, sizeof(out));
19701974

1971-
FunctionCall2Coll(&state->chooseFn,
1975+
procinfo = index_getprocinfo(index, 1, SPGIST_CHOOSE_PROC);
1976+
FunctionCall2Coll(procinfo,
19721977
index->rd_indcollation[0],
19731978
PointerGetDatum(&in),
19741979
PointerGetDatum(&out));

src/backend/access/spgist/spgkdtreeproc.c

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ spg_kd_config(PG_FUNCTION_ARGS)
3030

3131
cfg->prefixType = FLOAT8OID;
3232
cfg->labelType = VOIDOID; /* we don't need node labels */
33+
cfg->canReturnData = true;
3334
cfg->longValuesOK = false;
3435
PG_RETURN_VOID();
3536
}

src/backend/access/spgist/spgquadtreeproc.c

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ spg_quad_config(PG_FUNCTION_ARGS)
3030

3131
cfg->prefixType = POINTOID;
3232
cfg->labelType = VOIDOID; /* we don't need node labels */
33+
cfg->canReturnData = true;
3334
cfg->longValuesOK = false;
3435
PG_RETURN_VOID();
3536
}
@@ -324,6 +325,9 @@ spg_quad_leaf_consistent(PG_FUNCTION_ARGS)
324325
/* all tests are exact */
325326
out->recheck = false;
326327

328+
/* leafDatum is what it is... */
329+
out->leafValue = in->leafDatum;
330+
327331
switch (in->strategy)
328332
{
329333
case RTLeftStrategyNumber:

0 commit comments

Comments
 (0)