Skip to content

Commit 3695a55

Browse files
committed
Replace simple constant pg_am.amcanreturn with an AM support function.
The need for this was debated when we put in the index-only-scan feature, but at the time we had no near-term expectation of having AMs that could support such scans for only some indexes; so we kept it simple. However, the SP-GiST AM forces the issue, so let's fix it. This patch only installs the new API; no behavior actually changes.
1 parent 19d2231 commit 3695a55

File tree

15 files changed

+103
-46
lines changed

15 files changed

+103
-46
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -481,13 +481,6 @@
481481
<entry>Does the access method support multicolumn indexes?</entry>
482482
</row>
483483

484-
<row>
485-
<entry><structfield>amcanreturn</structfield></entry>
486-
<entry><type>bool</type></entry>
487-
<entry></entry>
488-
<entry>Can the access method return the contents of index entries?</entry>
489-
</row>
490-
491484
<row>
492485
<entry><structfield>amoptionalkey</structfield></entry>
493486
<entry><type>bool</type></entry>
@@ -622,6 +615,14 @@
622615
<entry>Post-<command>VACUUM</command> cleanup function</entry>
623616
</row>
624617

618+
<row>
619+
<entry><structfield>amcanreturn</structfield></entry>
620+
<entry><type>regproc</type></entry>
621+
<entry><literal><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.oid</literal></entry>
622+
<entry>Function to check whether index supports index-only scans,
623+
or zero if none</entry>
624+
</row>
625+
625626
<row>
626627
<entry><structfield>amcostestimate</structfield></entry>
627628
<entry><type>regproc</type></entry>

doc/src/sgml/indexam.sgml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,6 @@
134134
<structfield>amsearchnulls</structfield>, indicating that it supports
135135
<literal>IS NULL</> and <literal>IS NOT NULL</> clauses as search
136136
conditions.
137-
An index method can also set <structfield>amcanreturn</structfield>,
138-
indicating that it can support <firstterm>index-only scans</> by returning
139-
the indexed column values for an index entry in the form of an IndexTuple.
140-
(An example of an index AM that cannot do this is hash, which stores only
141-
the hash values not the original data.)
142137
</para>
143138

144139
</sect1>
@@ -278,6 +273,19 @@ amvacuumcleanup (IndexVacuumInfo *info,
278273

279274
<para>
280275
<programlisting>
276+
bool
277+
amcanreturn (Relation indexRelation);
278+
</programlisting>
279+
Check whether the index can support <firstterm>index-only scans</> by
280+
returning the indexed column values for an index entry in the form of an
281+
IndexTuple. Return TRUE if so, else FALSE. If the index AM can never
282+
support index-only scans (an example is hash, which stores only
283+
the hash values not the original data), it is sufficient to set its
284+
<structfield>amcanreturn</> field to zero in <structname>pg_am</>.
285+
</para>
286+
287+
<para>
288+
<programlisting>
281289
void
282290
amcostestimate (PlannerInfo *root,
283291
IndexOptInfo *index,
@@ -391,9 +399,9 @@ amgettuple (IndexScanDesc scan,
391399
</para>
392400

393401
<para>
394-
If the access method supports index-only scans (i.e.,
395-
<structfield>amcanreturn</structfield> is TRUE in its <structname>pg_am</>
396-
row), then on success it must also check
402+
If the index supports index-only scans (i.e.,
403+
<function>amcanreturn</function> returns TRUE for it),
404+
then on success the AM must also check
397405
<literal>scan-&gt;xs_want_itup</>, and if that is true it must return
398406
the original indexed data for the index entry, in the form of an
399407
<structname>IndexTuple</> pointer stored at <literal>scan-&gt;xs_itup</>,

src/backend/access/index/indexam.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* index_getbitmap - get all tuples from a scan
2727
* index_bulk_delete - bulk deletion of index tuples
2828
* index_vacuum_cleanup - post-deletion cleanup of an index
29+
* index_can_return - does index support index-only scans?
2930
* index_getprocid - get a support procedure OID
3031
* index_getprocinfo - get a support procedure's lookup info
3132
*
@@ -711,6 +712,27 @@ index_vacuum_cleanup(IndexVacuumInfo *info,
711712
return result;
712713
}
713714

715+
/* ----------------
716+
* index_can_return - does index support index-only scans?
717+
* ----------------
718+
*/
719+
bool
720+
index_can_return(Relation indexRelation)
721+
{
722+
FmgrInfo *procedure;
723+
724+
RELATION_CHECKS;
725+
726+
/* amcanreturn is optional; assume FALSE if not provided by AM */
727+
if (!RegProcedureIsValid(indexRelation->rd_am->amcanreturn))
728+
return false;
729+
730+
GET_REL_PROCEDURE(amcanreturn);
731+
732+
return DatumGetBool(FunctionCall1(procedure,
733+
PointerGetDatum(indexRelation)));
734+
}
735+
714736
/* ----------------
715737
* index_getprocid
716738
*

src/backend/access/nbtree/nbtree.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,3 +1091,14 @@ btvacuumpage(BTVacState *vstate, BlockNumber blkno, BlockNumber orig_blkno)
10911091
goto restart;
10921092
}
10931093
}
1094+
1095+
/*
1096+
* btcanreturn() -- Check whether btree indexes support index-only scans.
1097+
*
1098+
* btrees always do, so this is trivial.
1099+
*/
1100+
Datum
1101+
btcanreturn(PG_FUNCTION_ARGS)
1102+
{
1103+
PG_RETURN_BOOL(true);
1104+
}

src/backend/access/spgist/spgscan.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,10 @@ spggettuple(PG_FUNCTION_ARGS)
559559

560560
PG_RETURN_BOOL(false);
561561
}
562+
563+
Datum
564+
spgcanreturn(PG_FUNCTION_ARGS)
565+
{
566+
/* Not implemented yet */
567+
PG_RETURN_BOOL(false);
568+
}

src/backend/optimizer/path/indxpath.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,10 +1075,10 @@ check_index_only(RelOptInfo *rel, IndexOptInfo *index)
10751075
ListCell *lc;
10761076
int i;
10771077

1078-
/* Index-only scans must be enabled, and AM must be capable of it */
1078+
/* Index-only scans must be enabled, and index must be capable of them */
10791079
if (!enable_indexonlyscan)
10801080
return false;
1081-
if (!index->amcanreturn)
1081+
if (!index->canreturn)
10821082
return false;
10831083

10841084
/*

src/backend/optimizer/util/plancat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,8 +212,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
212212

213213
info->relam = indexRelation->rd_rel->relam;
214214
info->amcostestimate = indexRelation->rd_am->amcostestimate;
215+
info->canreturn = index_can_return(indexRelation);
215216
info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop;
216-
info->amcanreturn = indexRelation->rd_am->amcanreturn;
217217
info->amoptionalkey = indexRelation->rd_am->amoptionalkey;
218218
info->amsearcharray = indexRelation->rd_am->amsearcharray;
219219
info->amsearchnulls = indexRelation->rd_am->amsearchnulls;

src/include/access/genam.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
156156
void *callback_state);
157157
extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info,
158158
IndexBulkDeleteResult *stats);
159+
extern bool index_can_return(Relation indexRelation);
159160
extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum,
160161
uint16 procnum);
161162
extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum,

src/include/access/nbtree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ extern Datum btmarkpos(PG_FUNCTION_ARGS);
607607
extern Datum btrestrpos(PG_FUNCTION_ARGS);
608608
extern Datum btbulkdelete(PG_FUNCTION_ARGS);
609609
extern Datum btvacuumcleanup(PG_FUNCTION_ARGS);
610+
extern Datum btcanreturn(PG_FUNCTION_ARGS);
610611
extern Datum btoptions(PG_FUNCTION_ARGS);
611612

612613
/*

src/include/access/spgist.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ extern Datum spgmarkpos(PG_FUNCTION_ARGS);
182182
extern Datum spgrestrpos(PG_FUNCTION_ARGS);
183183
extern Datum spggetbitmap(PG_FUNCTION_ARGS);
184184
extern Datum spggettuple(PG_FUNCTION_ARGS);
185+
extern Datum spgcanreturn(PG_FUNCTION_ARGS);
185186

186187
/* spgutils.c */
187188
extern Datum spgoptions(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy