diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-12-21 12:43:36 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-12-21 12:43:36 -0500 |
commit | 1771ec9a82900665226022e77ad5f8a86d27a1be (patch) | |
tree | 96d3efea8982648b22f6f5fd305c70a5224d5dea /src/backend/access/spgist/spgutils.c | |
parent | 3cf7dfa7f3f6432788bf1df026fe79b63ee98401 (diff) | |
download | postgresql-1771ec9a82900665226022e77ad5f8a86d27a1be.tar.gz postgresql-1771ec9a82900665226022e77ad5f8a86d27a1be.zip |
Avoid trying to fetch metapage of an SPGist partitioned index.
This is necessary when spgcanreturn() is invoked on a partitioned
index, and the failure might be reachable in other scenarios as
well. The rest of what spgGetCache() does is perfectly sensible
for a partitioned index, so we should allow it to go through.
I think the main takeaway from this is that we lack sufficient test
coverage for non-btree partitioned indexes. Therefore, I added
simple test cases for brin and gin as well as spgist (hash and
gist AMs were covered already in indexing.sql).
Per bug #18256 from Alexander Lakhin. Although the known test case
only fails since v16 (3c569049b), I've got no faith at all that there
aren't other ways to reach this problem; so back-patch to all
supported branches.
Discussion: https://postgr.es/m/18256-0b0e1b6e4a620f1b@postgresql.org
Diffstat (limited to 'src/backend/access/spgist/spgutils.c')
-rw-r--r-- | src/backend/access/spgist/spgutils.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index e5b5f6c3340..927e04ddfb0 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -105,8 +105,6 @@ spgGetCache(Relation index) Oid atttype; spgConfigIn in; FmgrInfo *procinfo; - Buffer metabuffer; - SpGistMetaPageData *metadata; cache = MemoryContextAllocZero(index->rd_indexcxt, sizeof(SpGistCache)); @@ -151,19 +149,28 @@ spgGetCache(Relation index) fillTypeDesc(&cache->attPrefixType, cache->config.prefixType); fillTypeDesc(&cache->attLabelType, cache->config.labelType); - /* Last, get the lastUsedPages data from the metapage */ - metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO); - LockBuffer(metabuffer, BUFFER_LOCK_SHARE); + /* + * Finally, if it's a real index (not a partitioned one), get the + * lastUsedPages data from the metapage + */ + if (index->rd_rel->relkind != RELKIND_PARTITIONED_INDEX) + { + Buffer metabuffer; + SpGistMetaPageData *metadata; + + metabuffer = ReadBuffer(index, SPGIST_METAPAGE_BLKNO); + LockBuffer(metabuffer, BUFFER_LOCK_SHARE); - metadata = SpGistPageGetMeta(BufferGetPage(metabuffer)); + metadata = SpGistPageGetMeta(BufferGetPage(metabuffer)); - if (metadata->magicNumber != SPGIST_MAGIC_NUMBER) - elog(ERROR, "index \"%s\" is not an SP-GiST index", - RelationGetRelationName(index)); + if (metadata->magicNumber != SPGIST_MAGIC_NUMBER) + elog(ERROR, "index \"%s\" is not an SP-GiST index", + RelationGetRelationName(index)); - cache->lastUsedPages = metadata->lastUsedPages; + cache->lastUsedPages = metadata->lastUsedPages; - UnlockReleaseBuffer(metabuffer); + UnlockReleaseBuffer(metabuffer); + } index->rd_amcache = (void *) cache; } |