From cf891c0ed291ef7261e2e8ae369e195266603f7a Mon Sep 17 00:00:00 2001 From: Gurjeet Singh Date: Wed, 19 Jul 2023 19:20:32 -0700 Subject: [PATCH] Calculate index height after calling get_relation_info_hook Trying to calculate the height of a hypothetical index leads to error, because a hypothetical index does not have any on-disk pages. So move the index height calculation code to after the call to get_relation_info_hook. And honor the index height, if set on the hypothetical index. --- src/backend/optimizer/util/plancat.c | 59 ++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 39932d3c2d..f4ab3747e9 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -437,7 +437,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, * is partial then we have to use the same methods as we would for * a table, except we can be sure that the index is not larger * than the table. We must ignore partitioned indexes here as - * there are not physical indexes. + * these are not physical indexes. */ if (indexRelation->rd_rel->relkind != RELKIND_PARTITIONED_INDEX) { @@ -455,27 +455,12 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (info->tuples > rel->tuples) info->tuples = rel->tuples; } - - if (info->relam == BTREE_AM_OID) - { - /* - * For btrees, get tree height while we have the index - * open - */ - info->tree_height = _bt_getrootheight(indexRelation); - } - else - { - /* For other index types, just set it to "unknown" for now */ - info->tree_height = -1; - } } else { /* Zero these out for partitioned indexes */ info->pages = 0; info->tuples = 0.0; - info->tree_height = -1; } index_close(indexRelation, NoLock); @@ -534,6 +519,48 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, */ if (get_relation_info_hook) (*get_relation_info_hook) (root, relationObjectId, inhparent, rel); + + /* Estimate the height of indexes, if any. */ + if (hasindex) + { + ListCell *lc; + + foreach(lc, rel->indexlist) + { + IndexOptInfo *info = (IndexOptInfo*)lfirst(lc); + + /* + * If get_relation_info_hook marked an index as hypothetical, we + * honor its estimate of tree_height. If the hook implementation + * did not set a value for the tree height, then we set it to + * "unknown". + * + * For btrees, get tree height. For other index types, including + * for partitioned indexes, just set it to "unknown" for now. + */ + if (info->hypothetical) + { + if (info->tree_height == 0) + info->tree_height = -1; + } + else if (info->relam == BTREE_AM_OID) + { + /* + * We had opened this index above with appropriate lock. And + * since we're still holding that lock, we can get away with + * specifying NoLock here. + */ + Oid indexOid = info->indexoid; + Relation indexRelation = index_open(indexOid, NoLock); + + info->tree_height = _bt_getrootheight(indexRelation); + + index_close(indexRelation, NoLock); + } + else + info->tree_height = -1; + } + } } /* -- 2.35.1