Skip to content

Commit 2084701

Browse files
committed
pageinspect: Fix failure with hash_bitmap_info() for partitioned indexes
This function reads directly a page from a relation, relying on index_open() to open the index to read from. Unfortunately, this would crash when using partitioned indexes, as these can be opened with index_open() but they have no physical pages. Alexander has fixed the module, while I have written the test. Author: Alexander Lakhin, Michael Paquier Discussion: https://postgr.es/m/18246-f4d9ff7cb3af77e6@postgresql.org Backpatch-through: 12
1 parent a8dd62e commit 2084701

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

contrib/pageinspect/expected/hash.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
CREATE TABLE test_hash (a int, b text);
22
INSERT INTO test_hash VALUES (1, 'one');
33
CREATE INDEX test_hash_a_idx ON test_hash USING hash (a);
4+
CREATE TABLE test_hash_part (a int, b int) PARTITION BY RANGE (a);
5+
CREATE INDEX test_hash_part_idx ON test_hash_part USING hash(b);
46
\x
57
SELECT hash_page_type(get_raw_page('test_hash_a_idx', 0));
68
-[ RECORD 1 ]--+---------
@@ -44,6 +46,8 @@ SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5);
4446
ERROR: invalid overflow block number 5
4547
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 6);
4648
ERROR: block number 6 is out of range for relation "test_hash_a_idx"
49+
SELECT * FROM hash_bitmap_info('test_hash_part_idx', 1); -- error
50+
ERROR: "test_hash_part_idx" is not a hash index
4751
SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask,
4852
lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM
4953
hash_metapage_info(get_raw_page('test_hash_a_idx', 0));
@@ -203,3 +207,4 @@ SELECT hash_page_type(decode(repeat('00', :block_size), 'hex'));
203207
hash_page_type | unused
204208

205209
DROP TABLE test_hash;
210+
DROP TABLE test_hash_part;

contrib/pageinspect/hashfuncs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "access/hash.h"
1414
#include "access/htup_details.h"
15+
#include "access/relation.h"
1516
#include "catalog/pg_am.h"
1617
#include "catalog/pg_type.h"
1718
#include "funcapi.h"
@@ -27,6 +28,7 @@ PG_FUNCTION_INFO_V1(hash_page_items);
2728
PG_FUNCTION_INFO_V1(hash_bitmap_info);
2829
PG_FUNCTION_INFO_V1(hash_metapage_info);
2930

31+
#define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
3032
#define IS_HASH(r) ((r)->rd_rel->relam == HASH_AM_OID)
3133

3234
/* ------------------------------------------------
@@ -413,9 +415,9 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
413415
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
414416
errmsg("must be superuser to use raw page functions")));
415417

416-
indexRel = index_open(indexRelid, AccessShareLock);
418+
indexRel = relation_open(indexRelid, AccessShareLock);
417419

418-
if (!IS_HASH(indexRel))
420+
if (!IS_INDEX(indexRel) || !IS_HASH(indexRel))
419421
ereport(ERROR,
420422
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
421423
errmsg("\"%s\" is not a %s index",

contrib/pageinspect/sql/hash.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ CREATE TABLE test_hash (a int, b text);
22
INSERT INTO test_hash VALUES (1, 'one');
33
CREATE INDEX test_hash_a_idx ON test_hash USING hash (a);
44

5+
CREATE TABLE test_hash_part (a int, b int) PARTITION BY RANGE (a);
6+
CREATE INDEX test_hash_part_idx ON test_hash_part USING hash(b);
7+
58
\x
69

710
SELECT hash_page_type(get_raw_page('test_hash_a_idx', 0));
@@ -21,6 +24,7 @@ SELECT * FROM hash_bitmap_info('test_hash_a_idx', 3);
2124
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4);
2225
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5);
2326
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 6);
27+
SELECT * FROM hash_bitmap_info('test_hash_part_idx', 1); -- error
2428

2529

2630
SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask,
@@ -106,3 +110,4 @@ SELECT hash_page_stats(decode(repeat('00', :block_size), 'hex'));
106110
SELECT hash_page_type(decode(repeat('00', :block_size), 'hex'));
107111

108112
DROP TABLE test_hash;
113+
DROP TABLE test_hash_part;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy