Skip to content

Commit a8dd62e

Browse files
committed
pgstattuple: Fix failure with pgstathashindex() for partitioned indexes
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
1 parent c8bc807 commit a8dd62e

File tree

3 files changed

+11
-7
lines changed

3 files changed

+11
-7
lines changed

contrib/pgstattuple/expected/pgstattuple.out

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ ERROR: relation "test_hashidx" is not a GIN index
153153
-- check that using any of these functions with unsupported relations will fail
154154
create table test_partitioned (a int) partition by range (a);
155155
create index test_partitioned_index on test_partitioned(a);
156+
create index test_partitioned_hash_index on test_partitioned using hash(a);
156157
-- these should all fail
157158
select pgstattuple('test_partitioned');
158159
ERROR: cannot get tuple-level statistics for relation "test_partitioned"
@@ -171,7 +172,9 @@ ERROR: relation "test_partitioned" is not a btree index
171172
select pgstatginindex('test_partitioned');
172173
ERROR: relation "test_partitioned" is not a GIN index
173174
select pgstathashindex('test_partitioned');
174-
ERROR: "test_partitioned" is not an index
175+
ERROR: relation "test_partitioned" is not a hash index
176+
select pgstathashindex('test_partitioned_hash_index');
177+
ERROR: relation "test_partitioned_hash_index" is not a hash index
175178
create view test_view as select 1;
176179
-- these should all fail
177180
select pgstattuple('test_view');
@@ -188,7 +191,7 @@ ERROR: relation "test_view" is not a btree index
188191
select pgstatginindex('test_view');
189192
ERROR: relation "test_view" is not a GIN index
190193
select pgstathashindex('test_view');
191-
ERROR: "test_view" is not an index
194+
ERROR: relation "test_view" is not a hash index
192195
create foreign data wrapper dummy;
193196
create server dummy_server foreign data wrapper dummy;
194197
create foreign table test_foreign_table () server dummy_server;
@@ -207,7 +210,7 @@ ERROR: relation "test_foreign_table" is not a btree index
207210
select pgstatginindex('test_foreign_table');
208211
ERROR: relation "test_foreign_table" is not a GIN index
209212
select pgstathashindex('test_foreign_table');
210-
ERROR: "test_foreign_table" is not an index
213+
ERROR: relation "test_foreign_table" is not a hash index
211214
-- a partition of a partitioned table should work though
212215
create table test_partition partition of test_partitioned for values from (1) to (100);
213216
select pgstattuple('test_partition');
@@ -253,7 +256,7 @@ ERROR: relation "test_partition" is not a btree index
253256
select pgstatginindex('test_partition');
254257
ERROR: relation "test_partition" is not a GIN index
255258
select pgstathashindex('test_partition');
256-
ERROR: "test_partition" is not an index
259+
ERROR: relation "test_partition" is not a hash index
257260
-- an actual index of a partitioned table should work though
258261
create index test_partition_idx on test_partition(a);
259262
create index test_partition_hash_idx on test_partition using hash (a);

contrib/pgstattuple/pgstatindex.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,10 +600,9 @@ pgstathashindex(PG_FUNCTION_ARGS)
600600
float8 free_percent;
601601
uint64 total_space;
602602

603-
rel = index_open(relid, AccessShareLock);
603+
rel = relation_open(relid, AccessShareLock);
604604

605-
/* index_open() checks that it's an index */
606-
if (!IS_HASH(rel))
605+
if (!IS_INDEX(rel) || !IS_HASH(rel))
607606
ereport(ERROR,
608607
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
609608
errmsg("relation \"%s\" is not a hash index",

contrib/pgstattuple/sql/pgstattuple.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ select pgstatginindex('test_hashidx');
6565
-- check that using any of these functions with unsupported relations will fail
6666
create table test_partitioned (a int) partition by range (a);
6767
create index test_partitioned_index on test_partitioned(a);
68+
create index test_partitioned_hash_index on test_partitioned using hash(a);
6869
-- these should all fail
6970
select pgstattuple('test_partitioned');
7071
select pgstattuple('test_partitioned_index');
@@ -73,6 +74,7 @@ select pg_relpages('test_partitioned');
7374
select pgstatindex('test_partitioned');
7475
select pgstatginindex('test_partitioned');
7576
select pgstathashindex('test_partitioned');
77+
select pgstathashindex('test_partitioned_hash_index');
7678

7779
create view test_view as select 1;
7880
-- these should all fail

0 commit comments

Comments
 (0)