Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
pgstattuple: Fix failure with pgstathashindex() for partitioned indexes
authorMichael Paquier <michael@paquier.xyz>
Tue, 19 Dec 2023 06:20:53 +0000 (15:20 +0900)
committerMichael Paquier <michael@paquier.xyz>
Tue, 19 Dec 2023 06:20:53 +0000 (15:20 +0900)
As coded, the function relied on index_open() when opening an index
relation, allowing partitioned indexes to be processed by
pgstathashindex().  This was leading to a "could not open file" error
because partitioned indexes have no physical files, or to a crash with
an assertion failure (like on HEAD).

This issue is fixed by applying the same checks as the other stat
functions for indexes, with a lookup at both RELKIND_INDEX and the index
AM expected.

Author: Alexander Lakhin
Discussion: https://postgr.es/m/18246-f4d9ff7cb3af77e6@postgresql.org
Backpatch-through: 12

contrib/pgstattuple/expected/pgstattuple.out
contrib/pgstattuple/pgstatindex.c
contrib/pgstattuple/sql/pgstattuple.sql

index 9920dbfd4083e207e280683403d1bc1b0c6cb0d3..262633f065715d60cdf7c4ef07d4f1420f124446 100644 (file)
@@ -153,6 +153,7 @@ ERROR:  relation "test_hashidx" is not a GIN index
 -- check that using any of these functions with unsupported relations will fail
 create table test_partitioned (a int) partition by range (a);
 create index test_partitioned_index on test_partitioned(a);
+create index test_partitioned_hash_index on test_partitioned using hash(a);
 -- these should all fail
 select pgstattuple('test_partitioned');
 ERROR:  "test_partitioned" (partitioned table) is not supported
@@ -167,7 +168,9 @@ ERROR:  relation "test_partitioned" is not a btree index
 select pgstatginindex('test_partitioned');
 ERROR:  relation "test_partitioned" is not a GIN index
 select pgstathashindex('test_partitioned');
-ERROR:  "test_partitioned" is not an index
+ERROR:  relation "test_partitioned" is not a hash index
+select pgstathashindex('test_partitioned_hash_index');
+ERROR:  relation "test_partitioned_hash_index" is not a hash index
 create view test_view as select 1;
 -- these should all fail
 select pgstattuple('test_view');
@@ -181,7 +184,7 @@ ERROR:  relation "test_view" is not a btree index
 select pgstatginindex('test_view');
 ERROR:  relation "test_view" is not a GIN index
 select pgstathashindex('test_view');
-ERROR:  "test_view" is not an index
+ERROR:  relation "test_view" is not a hash index
 create foreign data wrapper dummy;
 create server dummy_server foreign data wrapper dummy;
 create foreign table test_foreign_table () server dummy_server;
@@ -197,7 +200,7 @@ ERROR:  relation "test_foreign_table" is not a btree index
 select pgstatginindex('test_foreign_table');
 ERROR:  relation "test_foreign_table" is not a GIN index
 select pgstathashindex('test_foreign_table');
-ERROR:  "test_foreign_table" is not an index
+ERROR:  relation "test_foreign_table" is not a hash index
 -- a partition of a partitioned table should work though
 create table test_partition partition of test_partitioned for values from (1) to (100);
 select pgstattuple('test_partition');
@@ -224,7 +227,7 @@ ERROR:  relation "test_partition" is not a btree index
 select pgstatginindex('test_partition');
 ERROR:  relation "test_partition" is not a GIN index
 select pgstathashindex('test_partition');
-ERROR:  "test_partition" is not an index
+ERROR:  relation "test_partition" is not a hash index
 -- an actual index of a partitioned table should work though
 create index test_partition_idx on test_partition(a);
 create index test_partition_hash_idx on test_partition using hash (a);
index f8faefc60ae119c207a915dfac37921ad79a8b14..74b2651d973229718f2c141d5fa999d9dc93f538 100644 (file)
@@ -615,10 +615,9 @@ pgstathashindex(PG_FUNCTION_ARGS)
    float8      free_percent;
    uint64      total_space;
 
-   rel = index_open(relid, AccessShareLock);
+   rel = relation_open(relid, AccessShareLock);
 
-   /* index_open() checks that it's an index */
-   if (!IS_HASH(rel))
+   if (!IS_INDEX(rel) || !IS_HASH(rel))
        ereport(ERROR,
                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                 errmsg("relation \"%s\" is not a hash index",
index cfa540302da09db78cad9ad422f0f5b9cd9b0ba7..6a6846fd9ae44a9978e42c52e6283b4ee8c7edab 100644 (file)
@@ -65,6 +65,7 @@ select pgstatginindex('test_hashidx');
 -- check that using any of these functions with unsupported relations will fail
 create table test_partitioned (a int) partition by range (a);
 create index test_partitioned_index on test_partitioned(a);
+create index test_partitioned_hash_index on test_partitioned using hash(a);
 -- these should all fail
 select pgstattuple('test_partitioned');
 select pgstattuple('test_partitioned_index');
@@ -73,6 +74,7 @@ select pg_relpages('test_partitioned');
 select pgstatindex('test_partitioned');
 select pgstatginindex('test_partitioned');
 select pgstathashindex('test_partitioned');
+select pgstathashindex('test_partitioned_hash_index');
 
 create view test_view as select 1;
 -- these should all fail