Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf18aa1b

Browse files
committed
pageinspect: Change block number arguments to bigint
Block numbers are 32-bit unsigned integers. Therefore, the smallestSQL integer type that they can fit in is bigint. However, in thepageinspect module, most input and output parameters dealing withblock numbers were declared as int. The behavior with block numberslarger than a signed 32-bit integer was therefore dubious. Changethese arguments to type bigint and add some more explicit errorchecking on the block range.(Other contrib modules appear to do this correctly already.)Since we are changing argument types of existing functions, in orderto not misbehave if the binary is updated before the extension isupdated, we need to create new C symbols for the entry points, similarto how it's done in other extensions as well.Reported-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://www.postgresql.org/message-id/flat/d8f6bdd536df403b9b33816e9f7e0b9d@G08CNEXMBPEKD05.g08.fujitsu.local
1 parentee79a54 commitf18aa1b

18 files changed

+328
-31
lines changed

‎contrib/pageinspect/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ DATA = pageinspect--1.8--1.9.sql \
2121
pageinspect--1.0--1.1.sql
2222
PGFILEDESC = "pageinspect - functions to inspect contents of database pages"
2323

24-
REGRESS = page btree brin gin gist hash checksum
24+
REGRESS = page btree brin gin gist hash checksum oldextversions
2525

2626
ifdefUSE_PGXS
2727
PG_CONFIG = pg_config

‎contrib/pageinspect/brinfuncs.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,18 @@ brin_page_items(PG_FUNCTION_ARGS)
252252
intatt=attno-1;
253253

254254
values[0]=UInt16GetDatum(offset);
255-
values[1]=UInt32GetDatum(dtup->bt_blkno);
255+
switch (TupleDescAttr(tupdesc,1)->atttypid)
256+
{
257+
caseINT8OID:
258+
values[1]=Int64GetDatum((int64)dtup->bt_blkno);
259+
break;
260+
caseINT4OID:
261+
/* support for old extension version */
262+
values[1]=UInt32GetDatum(dtup->bt_blkno);
263+
break;
264+
default:
265+
elog(ERROR,"incorrect output types");
266+
}
256267
values[2]=UInt16GetDatum(attno);
257268
values[3]=BoolGetDatum(dtup->bt_columns[att].bv_allnulls);
258269
values[4]=BoolGetDatum(dtup->bt_columns[att].bv_hasnulls);

‎contrib/pageinspect/btreefuncs.c

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@
4141
#include"utils/varlena.h"
4242

4343
PG_FUNCTION_INFO_V1(bt_metap);
44+
PG_FUNCTION_INFO_V1(bt_page_items_1_9);
4445
PG_FUNCTION_INFO_V1(bt_page_items);
4546
PG_FUNCTION_INFO_V1(bt_page_items_bytea);
47+
PG_FUNCTION_INFO_V1(bt_page_stats_1_9);
4648
PG_FUNCTION_INFO_V1(bt_page_stats);
4749

4850
#defineIS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX)
@@ -160,11 +162,11 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat)
160162
* Usage: SELECT * FROM bt_page_stats('t1_pkey', 1);
161163
* -----------------------------------------------
162164
*/
163-
Datum
164-
bt_page_stats(PG_FUNCTION_ARGS)
165+
staticDatum
166+
bt_page_stats_internal(PG_FUNCTION_ARGS,enumpageinspect_versionext_version)
165167
{
166168
text*relname=PG_GETARG_TEXT_PP(0);
167-
uint32blkno=PG_GETARG_UINT32(1);
169+
int64blkno=(ext_version==PAGEINSPECT_V1_8 ?PG_GETARG_UINT32(1) :PG_GETARG_INT64(1));
168170
Bufferbuffer;
169171
Relationrel;
170172
RangeVar*relrv;
@@ -197,8 +199,15 @@ bt_page_stats(PG_FUNCTION_ARGS)
197199
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
198200
errmsg("cannot access temporary tables of other sessions")));
199201

202+
if (blkno<0||blkno>MaxBlockNumber)
203+
ereport(ERROR,
204+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
205+
errmsg("invalid block number")));
206+
200207
if (blkno==0)
201-
elog(ERROR,"block 0 is a meta page");
208+
ereport(ERROR,
209+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
210+
errmsg("block 0 is a meta page")));
202211

203212
CHECK_RELATION_BLOCK_RANGE(rel,blkno);
204213

@@ -219,16 +228,16 @@ bt_page_stats(PG_FUNCTION_ARGS)
219228
elog(ERROR,"return type must be a row type");
220229

221230
j=0;
222-
values[j++]=psprintf("%d",stat.blkno);
231+
values[j++]=psprintf("%u",stat.blkno);
223232
values[j++]=psprintf("%c",stat.type);
224-
values[j++]=psprintf("%d",stat.live_items);
225-
values[j++]=psprintf("%d",stat.dead_items);
226-
values[j++]=psprintf("%d",stat.avg_item_size);
227-
values[j++]=psprintf("%d",stat.page_size);
228-
values[j++]=psprintf("%d",stat.free_size);
229-
values[j++]=psprintf("%d",stat.btpo_prev);
230-
values[j++]=psprintf("%d",stat.btpo_next);
231-
values[j++]=psprintf("%d", (stat.type=='d') ?stat.btpo.xact :stat.btpo.level);
233+
values[j++]=psprintf("%u",stat.live_items);
234+
values[j++]=psprintf("%u",stat.dead_items);
235+
values[j++]=psprintf("%u",stat.avg_item_size);
236+
values[j++]=psprintf("%u",stat.page_size);
237+
values[j++]=psprintf("%u",stat.free_size);
238+
values[j++]=psprintf("%u",stat.btpo_prev);
239+
values[j++]=psprintf("%u",stat.btpo_next);
240+
values[j++]=psprintf("%u", (stat.type=='d') ?stat.btpo.xact :stat.btpo.level);
232241
values[j++]=psprintf("%d",stat.btpo_flags);
233242

234243
tuple=BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc),
@@ -239,6 +248,19 @@ bt_page_stats(PG_FUNCTION_ARGS)
239248
PG_RETURN_DATUM(result);
240249
}
241250

251+
Datum
252+
bt_page_stats_1_9(PG_FUNCTION_ARGS)
253+
{
254+
returnbt_page_stats_internal(fcinfo,PAGEINSPECT_V1_9);
255+
}
256+
257+
/* entry point for old extension version */
258+
Datum
259+
bt_page_stats(PG_FUNCTION_ARGS)
260+
{
261+
returnbt_page_stats_internal(fcinfo,PAGEINSPECT_V1_8);
262+
}
263+
242264

243265
/*
244266
* cross-call data structure for SRF
@@ -405,11 +427,11 @@ bt_page_print_tuples(struct user_args *uargs)
405427
* Usage: SELECT * FROM bt_page_items('t1_pkey', 1);
406428
*-------------------------------------------------------
407429
*/
408-
Datum
409-
bt_page_items(PG_FUNCTION_ARGS)
430+
staticDatum
431+
bt_page_items_internal(PG_FUNCTION_ARGS,enumpageinspect_versionext_version)
410432
{
411433
text*relname=PG_GETARG_TEXT_PP(0);
412-
uint32blkno=PG_GETARG_UINT32(1);
434+
int64blkno=(ext_version==PAGEINSPECT_V1_8 ?PG_GETARG_UINT32(1) :PG_GETARG_INT64(1));
413435
Datumresult;
414436
FuncCallContext*fctx;
415437
MemoryContextmctx;
@@ -447,8 +469,15 @@ bt_page_items(PG_FUNCTION_ARGS)
447469
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
448470
errmsg("cannot access temporary tables of other sessions")));
449471

472+
if (blkno<0||blkno>MaxBlockNumber)
473+
ereport(ERROR,
474+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
475+
errmsg("invalid block number")));
476+
450477
if (blkno==0)
451-
elog(ERROR,"block 0 is a meta page");
478+
ereport(ERROR,
479+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
480+
errmsg("block 0 is a meta page")));
452481

453482
CHECK_RELATION_BLOCK_RANGE(rel,blkno);
454483

@@ -506,6 +535,19 @@ bt_page_items(PG_FUNCTION_ARGS)
506535
SRF_RETURN_DONE(fctx);
507536
}
508537

538+
Datum
539+
bt_page_items_1_9(PG_FUNCTION_ARGS)
540+
{
541+
returnbt_page_items_internal(fcinfo,PAGEINSPECT_V1_9);
542+
}
543+
544+
/* entry point for old extension version */
545+
Datum
546+
bt_page_items(PG_FUNCTION_ARGS)
547+
{
548+
returnbt_page_items_internal(fcinfo,PAGEINSPECT_V1_8);
549+
}
550+
509551
/*-------------------------------------------------------
510552
* bt_page_items_bytea()
511553
*

‎contrib/pageinspect/expected/btree.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ oldest_xact | 0
1414
last_cleanup_num_tuples | -1
1515
allequalimage | t
1616

17+
SELECT * FROM bt_page_stats('test1_a_idx', -1);
18+
ERROR: invalid block number
1719
SELECT * FROM bt_page_stats('test1_a_idx', 0);
1820
ERROR: block 0 is a meta page
1921
SELECT * FROM bt_page_stats('test1_a_idx', 1);
@@ -32,6 +34,8 @@ btpo_flags | 3
3234

3335
SELECT * FROM bt_page_stats('test1_a_idx', 2);
3436
ERROR: block number out of range
37+
SELECT * FROM bt_page_items('test1_a_idx', -1);
38+
ERROR: invalid block number
3539
SELECT * FROM bt_page_items('test1_a_idx', 0);
3640
ERROR: block 0 is a meta page
3741
SELECT * FROM bt_page_items('test1_a_idx', 1);
@@ -48,6 +52,8 @@ tids |
4852

4953
SELECT * FROM bt_page_items('test1_a_idx', 2);
5054
ERROR: block number out of range
55+
SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', -1));
56+
ERROR: invalid block number
5157
SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 0));
5258
ERROR: block is a meta page
5359
SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 1));

‎contrib/pageinspect/expected/gin.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ FROM gin_leafpage_items(get_raw_page('test1_y_idx',
3535
-[ RECORD 1 ]
3636
?column? | t
3737

38+
DROP TABLE test1;

‎contrib/pageinspect/expected/hash.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ hash_page_type | bitmap
2828

2929
SELECT hash_page_type(get_raw_page('test_hash_a_idx', 6));
3030
ERROR: block number 6 is out of range for relation "test_hash_a_idx"
31+
SELECT * FROM hash_bitmap_info('test_hash_a_idx', -1);
32+
ERROR: invalid block number
3133
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 0);
3234
ERROR: invalid overflow block number 0
3335
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 1);
@@ -40,6 +42,8 @@ SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4);
4042
ERROR: invalid overflow block number 4
4143
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5);
4244
ERROR: invalid overflow block number 5
45+
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 6);
46+
ERROR: block number 6 is out of range for relation "test_hash_a_idx"
4347
SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask,
4448
lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM
4549
hash_metapage_info(get_raw_page('test_hash_a_idx', 0));
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
-- test old extension version entry points
2+
DROP EXTENSION pageinspect;
3+
CREATE EXTENSION pageinspect VERSION '1.8';
4+
CREATE TABLE test1 (a int8, b text);
5+
INSERT INTO test1 VALUES (72057594037927937, 'text');
6+
CREATE INDEX test1_a_idx ON test1 USING btree (a);
7+
-- from page.sql
8+
SELECT octet_length(get_raw_page('test1', 0)) AS main_0;
9+
main_0
10+
--------
11+
8192
12+
(1 row)
13+
14+
SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0;
15+
main_0
16+
--------
17+
8192
18+
(1 row)
19+
20+
SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_test;
21+
silly_checksum_test
22+
---------------------
23+
t
24+
(1 row)
25+
26+
-- from btree.sql
27+
SELECT * FROM bt_page_stats('test1_a_idx', 1);
28+
blkno | type | live_items | dead_items | avg_item_size | page_size | free_size | btpo_prev | btpo_next | btpo | btpo_flags
29+
-------+------+------------+------------+---------------+-----------+-----------+-----------+-----------+------+------------
30+
1 | l | 1 | 0 | 16 | 8192 | 8128 | 0 | 0 | 0 | 3
31+
(1 row)
32+
33+
SELECT * FROM bt_page_items('test1_a_idx', 1);
34+
itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | tids
35+
------------+-------+---------+-------+------+-------------------------+------+-------+------
36+
1 | (0,1) | 16 | f | f | 01 00 00 00 00 00 00 01 | f | (0,1) |
37+
(1 row)
38+
39+
DROP TABLE test1;
40+
DROP EXTENSION pageinspect;

‎contrib/pageinspect/expected/page.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ SELECT octet_length(get_raw_page('test1', 'vm', 0)) AS vm_0;
3232

3333
SELECT octet_length(get_raw_page('test1', 'vm', 1)) AS vm_1;
3434
ERROR: block number 1 is out of range for relation "test1"
35+
SELECT octet_length(get_raw_page('test1', 'main', -1));
36+
ERROR: invalid block number
3537
SELECT octet_length(get_raw_page('xxx', 'main', 0));
3638
ERROR: relation "xxx" does not exist
3739
SELECT octet_length(get_raw_page('test1', 'xxx', 0));
@@ -55,6 +57,8 @@ SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_
5557
t
5658
(1 row)
5759

60+
SELECT page_checksum(get_raw_page('test1', 0), -1);
61+
ERROR: invalid block number
5862
SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bits)
5963
FROM heap_page_items(get_raw_page('test1', 0));
6064
tuple_data_split

‎contrib/pageinspect/hashfuncs.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ Datum
390390
hash_bitmap_info(PG_FUNCTION_ARGS)
391391
{
392392
OidindexRelid=PG_GETARG_OID(0);
393-
uint64ovflblkno=PG_GETARG_INT64(1);
393+
int64ovflblkno=PG_GETARG_INT64(1);
394394
HashMetaPagemetap;
395395
Buffermetabuf,
396396
mapbuf;
@@ -425,11 +425,16 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
425425
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
426426
errmsg("cannot access temporary tables of other sessions")));
427427

428+
if (ovflblkno<0||ovflblkno>MaxBlockNumber)
429+
ereport(ERROR,
430+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
431+
errmsg("invalid block number")));
432+
428433
if (ovflblkno >=RelationGetNumberOfBlocks(indexRel))
429434
ereport(ERROR,
430435
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
431-
errmsg("block number"UINT64_FORMAT" is out of range for relation \"%s\"",
432-
ovflblkno,RelationGetRelationName(indexRel))));
436+
errmsg("block number%lld is out of range for relation \"%s\"",
437+
(long longint)ovflblkno,RelationGetRelationName(indexRel))));
433438

434439
/* Read the metapage so we can determine which bitmap page to use */
435440
metabuf=_hash_getbuf(indexRel,HASH_METAPAGE,HASH_READ,LH_META_PAGE);

‎contrib/pageinspect/pageinspect--1.8--1.9.sql

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,80 @@ CREATE FUNCTION gist_page_items(IN page bytea,
3939
RETURNS SETOF record
4040
AS'MODULE_PATHNAME','gist_page_items'
4141
LANGUAGE C STRICT PARALLEL SAFE;
42+
43+
--
44+
-- get_raw_page()
45+
--
46+
DROPFUNCTION get_raw_page(text, int4);
47+
CREATEFUNCTIONget_raw_page(text, int8)
48+
RETURNSbytea
49+
AS'MODULE_PATHNAME','get_raw_page_1_9'
50+
LANGUAGE C STRICT PARALLEL SAFE;
51+
52+
DROPFUNCTION get_raw_page(text,text, int4);
53+
CREATEFUNCTIONget_raw_page(text,text, int8)
54+
RETURNSbytea
55+
AS'MODULE_PATHNAME','get_raw_page_fork_1_9'
56+
LANGUAGE C STRICT PARALLEL SAFE;
57+
58+
--
59+
-- page_checksum()
60+
--
61+
DROPFUNCTION page_checksum(IN pagebytea,IN blkno int4);
62+
CREATEFUNCTIONpage_checksum(IN pagebytea,IN blkno int8)
63+
RETURNSsmallint
64+
AS'MODULE_PATHNAME','page_checksum_1_9'
65+
LANGUAGE C STRICT PARALLEL SAFE;
66+
67+
--
68+
-- bt_page_stats()
69+
--
70+
DROPFUNCTION bt_page_stats(text, int4);
71+
CREATEFUNCTIONbt_page_stats(IN relnametext,IN blkno int8,
72+
OUT blkno int8,
73+
OUT type"char",
74+
OUT live_items int4,
75+
OUT dead_items int4,
76+
OUT avg_item_size int4,
77+
OUT page_size int4,
78+
OUT free_size int4,
79+
OUT btpo_prev int8,
80+
OUT btpo_next int8,
81+
OUT btpo int4,
82+
OUT btpo_flags int4)
83+
AS'MODULE_PATHNAME','bt_page_stats_1_9'
84+
LANGUAGE C STRICT PARALLEL SAFE;
85+
86+
--
87+
-- bt_page_items()
88+
--
89+
DROPFUNCTION bt_page_items(text, int4);
90+
CREATEFUNCTIONbt_page_items(IN relnametext,IN blkno int8,
91+
OUT itemoffsetsmallint,
92+
OUT ctid tid,
93+
OUT itemlensmallint,
94+
OUT nulls bool,
95+
OUT vars bool,
96+
OUT datatext,
97+
OUT deadboolean,
98+
OUT htid tid,
99+
OUT tids tid[])
100+
RETURNS SETOF record
101+
AS'MODULE_PATHNAME','bt_page_items_1_9'
102+
LANGUAGE C STRICT PARALLEL SAFE;
103+
104+
--
105+
-- brin_page_items()
106+
--
107+
DROPFUNCTION brin_page_items(IN pagebytea,IN index_oid regclass);
108+
CREATEFUNCTIONbrin_page_items(IN pagebytea,IN index_oid regclass,
109+
OUT itemoffsetint,
110+
OUT blknum int8,
111+
OUT attnumint,
112+
OUT allnulls bool,
113+
OUT hasnulls bool,
114+
OUT placeholder bool,
115+
OUT valuetext)
116+
RETURNS SETOF record
117+
AS'MODULE_PATHNAME','brin_page_items'
118+
LANGUAGE C STRICT PARALLEL SAFE;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp