Skip to content

Commit 56fead4

Browse files
committed
Add amgettreeheight index AM API routine
The only current implementation is for btree where it calls _bt_getrootheight(). Other index types can now also use this to pass information to their amcostestimate routine. Previously, btree was hardcoded and other index types could not hook into the optimizer at this point. Author: Mark Dilger <mark.dilger@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/E72EAA49-354D-4C2E-8EB9-255197F55330@enterprisedb.com
1 parent f5050f7 commit 56fead4

File tree

12 files changed

+48
-7
lines changed

12 files changed

+48
-7
lines changed

contrib/bloom/blutils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ blhandler(PG_FUNCTION_ARGS)
137137
amroutine->amvacuumcleanup = blvacuumcleanup;
138138
amroutine->amcanreturn = NULL;
139139
amroutine->amcostestimate = blcostestimate;
140+
amroutine->amgettreeheight = NULL;
140141
amroutine->amoptions = bloptions;
141142
amroutine->amproperty = NULL;
142143
amroutine->ambuildphasename = NULL;

doc/src/sgml/indexam.sgml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ typedef struct IndexAmRoutine
146146
amvacuumcleanup_function amvacuumcleanup;
147147
amcanreturn_function amcanreturn; /* can be NULL */
148148
amcostestimate_function amcostestimate;
149+
amgettreeheight_function amgettreeheight; /* can be NULL */
149150
amoptions_function amoptions;
150151
amproperty_function amproperty; /* can be NULL */
151152
ambuildphasename_function ambuildphasename; /* can be NULL */
@@ -480,6 +481,21 @@ amcostestimate (PlannerInfo *root,
480481

481482
<para>
482483
<programlisting>
484+
int
485+
amgettreeheight (Relation rel);
486+
</programlisting>
487+
Compute the height of a tree-shaped index. This information is supplied to
488+
the <function>amcostestimate</function> function in
489+
<literal>path->indexinfo->tree_height</literal> and can be used to support
490+
the cost estimation. The result is not used anywhere else, so this
491+
function can actually be used to compute any kind of data (that fits into
492+
an integer) about the index that the cost estimation function might want to
493+
know. If the computation is expensive, it could be useful to cache the
494+
result as part of <literal>RelationData.rd_amcache</literal>.
495+
</para>
496+
497+
<para>
498+
<programlisting>
483499
bytea *
484500
amoptions (ArrayType *reloptions,
485501
bool validate);

src/backend/access/brin/brin.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ brinhandler(PG_FUNCTION_ARGS)
279279
amroutine->amvacuumcleanup = brinvacuumcleanup;
280280
amroutine->amcanreturn = NULL;
281281
amroutine->amcostestimate = brincostestimate;
282+
amroutine->amgettreeheight = NULL;
282283
amroutine->amoptions = brinoptions;
283284
amroutine->amproperty = NULL;
284285
amroutine->ambuildphasename = NULL;

src/backend/access/gin/ginutil.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ ginhandler(PG_FUNCTION_ARGS)
6969
amroutine->amvacuumcleanup = ginvacuumcleanup;
7070
amroutine->amcanreturn = NULL;
7171
amroutine->amcostestimate = gincostestimate;
72+
amroutine->amgettreeheight = NULL;
7273
amroutine->amoptions = ginoptions;
7374
amroutine->amproperty = NULL;
7475
amroutine->ambuildphasename = NULL;

src/backend/access/gist/gist.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ gisthandler(PG_FUNCTION_ARGS)
9191
amroutine->amvacuumcleanup = gistvacuumcleanup;
9292
amroutine->amcanreturn = gistcanreturn;
9393
amroutine->amcostestimate = gistcostestimate;
94+
amroutine->amgettreeheight = NULL;
9495
amroutine->amoptions = gistoptions;
9596
amroutine->amproperty = gistproperty;
9697
amroutine->ambuildphasename = NULL;

src/backend/access/hash/hash.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ hashhandler(PG_FUNCTION_ARGS)
8989
amroutine->amvacuumcleanup = hashvacuumcleanup;
9090
amroutine->amcanreturn = NULL;
9191
amroutine->amcostestimate = hashcostestimate;
92+
amroutine->amgettreeheight = NULL;
9293
amroutine->amoptions = hashoptions;
9394
amroutine->amproperty = NULL;
9495
amroutine->ambuildphasename = NULL;

src/backend/access/nbtree/nbtree.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ bthandler(PG_FUNCTION_ARGS)
133133
amroutine->amvacuumcleanup = btvacuumcleanup;
134134
amroutine->amcanreturn = btcanreturn;
135135
amroutine->amcostestimate = btcostestimate;
136+
amroutine->amgettreeheight = btgettreeheight;
136137
amroutine->amoptions = btoptions;
137138
amroutine->amproperty = btproperty;
138139
amroutine->ambuildphasename = btbuildphasename;
@@ -1445,3 +1446,12 @@ btcanreturn(Relation index, int attno)
14451446
{
14461447
return true;
14471448
}
1449+
1450+
/*
1451+
* btgettreeheight() -- Compute tree height for use by btcostestimate().
1452+
*/
1453+
int
1454+
btgettreeheight(Relation rel)
1455+
{
1456+
return _bt_getrootheight(rel);
1457+
}

src/backend/access/spgist/spgutils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ spghandler(PG_FUNCTION_ARGS)
7676
amroutine->amvacuumcleanup = spgvacuumcleanup;
7777
amroutine->amcanreturn = spgcanreturn;
7878
amroutine->amcostestimate = spgcostestimate;
79+
amroutine->amgettreeheight = NULL;
7980
amroutine->amoptions = spgoptions;
8081
amroutine->amproperty = spgproperty;
8182
amroutine->ambuildphasename = NULL;

src/backend/optimizer/util/plancat.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
241241
Oid indexoid = lfirst_oid(l);
242242
Relation indexRelation;
243243
Form_pg_index index;
244-
IndexAmRoutine *amroutine;
244+
IndexAmRoutine *amroutine = NULL;
245245
IndexOptInfo *info;
246246
int ncolumns,
247247
nkeycolumns;
@@ -485,13 +485,12 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
485485
info->tuples = rel->tuples;
486486
}
487487

488-
if (info->relam == BTREE_AM_OID)
488+
/*
489+
* Get tree height while we have the index open
490+
*/
491+
if (amroutine->amgettreeheight)
489492
{
490-
/*
491-
* For btrees, get tree height while we have the index
492-
* open
493-
*/
494-
info->tree_height = _bt_getrootheight(indexRelation);
493+
info->tree_height = amroutine->amgettreeheight(indexRelation);
495494
}
496495
else
497496
{

src/include/access/amapi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ typedef void (*amcostestimate_function) (struct PlannerInfo *root,
140140
double *indexCorrelation,
141141
double *indexPages);
142142

143+
/* estimate height of a tree-structured index
144+
*
145+
* XXX This just computes a value that is later used by amcostestimate. This
146+
* API could be expanded to support passing more values if the need arises.
147+
*/
148+
typedef int (*amgettreeheight_function) (Relation rel);
149+
143150
/* parse index reloptions */
144151
typedef bytea *(*amoptions_function) (Datum reloptions,
145152
bool validate);
@@ -272,6 +279,7 @@ typedef struct IndexAmRoutine
272279
amvacuumcleanup_function amvacuumcleanup;
273280
amcanreturn_function amcanreturn; /* can be NULL */
274281
amcostestimate_function amcostestimate;
282+
amgettreeheight_function amgettreeheight; /* can be NULL */
275283
amoptions_function amoptions;
276284
amproperty_function amproperty; /* can be NULL */
277285
ambuildphasename_function ambuildphasename; /* can be NULL */

src/include/access/nbtree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,7 @@ extern IndexBulkDeleteResult *btbulkdelete(IndexVacuumInfo *info,
11861186
extern IndexBulkDeleteResult *btvacuumcleanup(IndexVacuumInfo *info,
11871187
IndexBulkDeleteResult *stats);
11881188
extern bool btcanreturn(Relation index, int attno);
1189+
extern int btgettreeheight(Relation rel);
11891190

11901191
/*
11911192
* prototypes for internal functions in nbtree.c

src/test/modules/dummy_index_am/dummy_index_am.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ dihandler(PG_FUNCTION_ARGS)
308308
amroutine->amvacuumcleanup = divacuumcleanup;
309309
amroutine->amcanreturn = NULL;
310310
amroutine->amcostestimate = dicostestimate;
311+
amroutine->amgettreeheight = NULL;
311312
amroutine->amoptions = dioptions;
312313
amroutine->amproperty = NULL;
313314
amroutine->ambuildphasename = NULL;

0 commit comments

Comments
 (0)