Skip to content

Commit 218eb5c

Browse files
author
Commitfest Bot
committed
[CF 3733] v20250328 - Amcheck verification of GiST and GIN
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/3733 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/d2ee3c1e-f51b-46bf-8307-be545e3b85d2@vondra.me Author(s): Heikki Linnakangas, Andrey Borodin, Grigory Kryachko
2 parents a5419bc + 48143f4 commit 218eb5c

File tree

17 files changed

+1508
-215
lines changed

17 files changed

+1508
-215
lines changed

contrib/amcheck/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
MODULE_big = amcheck
44
OBJS = \
55
$(WIN32RES) \
6+
verify_common.o \
7+
verify_gin.o \
68
verify_heapam.o \
79
verify_nbtree.o
810

911
EXTENSION = amcheck
10-
DATA = amcheck--1.3--1.4.sql amcheck--1.2--1.3.sql amcheck--1.1--1.2.sql amcheck--1.0--1.1.sql amcheck--1.0.sql
12+
DATA = amcheck--1.2--1.3.sql amcheck--1.1--1.2.sql amcheck--1.0--1.1.sql amcheck--1.0.sql \
13+
amcheck--1.3--1.4.sql amcheck--1.4--1.5.sql
1114
PGFILEDESC = "amcheck - function for verifying relation integrity"
1215

13-
REGRESS = check check_btree check_heap
16+
REGRESS = check check_btree check_gin check_heap
1417

1518
EXTRA_INSTALL = contrib/pg_walinspect
1619
TAP_TESTS = 1
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* contrib/amcheck/amcheck--1.4--1.5.sql */
2+
3+
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
4+
\echo Use "ALTER EXTENSION amcheck UPDATE TO '1.5'" to load this file. \quit
5+
6+
7+
-- gin_index_check()
8+
--
9+
CREATE FUNCTION gin_index_check(index regclass)
10+
RETURNS VOID
11+
AS 'MODULE_PATHNAME', 'gin_index_check'
12+
LANGUAGE C STRICT;
13+
14+
REVOKE ALL ON FUNCTION gin_index_check(regclass) FROM PUBLIC;

contrib/amcheck/amcheck.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# amcheck extension
22
comment = 'functions for verifying relation integrity'
3-
default_version = '1.4'
3+
default_version = '1.5'
44
module_pathname = '$libdir/amcheck'
55
relocatable = true

contrib/amcheck/expected/check_btree.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ ERROR: could not open relation with OID 17
5757
BEGIN;
5858
CREATE INDEX bttest_a_brin_idx ON bttest_a USING brin(id);
5959
SELECT bt_index_parent_check('bttest_a_brin_idx');
60-
ERROR: only B-Tree indexes are supported as targets for verification
61-
DETAIL: Relation "bttest_a_brin_idx" is not a B-Tree index.
60+
ERROR: expected "btree" index as targets for verification
61+
DETAIL: Relation "bttest_a_brin_idx" is a brin index.
6262
ROLLBACK;
6363
-- normal check outside of xact
6464
SELECT bt_index_check('bttest_a_idx');
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
-- Test of index bulk load
2+
SELECT setseed(1);
3+
setseed
4+
---------
5+
6+
(1 row)
7+
8+
CREATE TABLE "gin_check"("Column1" int[]);
9+
-- posting trees (frequently used entries)
10+
INSERT INTO gin_check select array_agg(round(random()*255) ) from generate_series(1, 100000) as i group by i % 10000;
11+
-- posting leaves (sparse entries)
12+
INSERT INTO gin_check select array_agg(255 + round(random()*100)) from generate_series(1, 100) as i group by i % 100;
13+
CREATE INDEX gin_check_idx on "gin_check" USING GIN("Column1");
14+
SELECT gin_index_check('gin_check_idx');
15+
gin_index_check
16+
-----------------
17+
18+
(1 row)
19+
20+
-- cleanup
21+
DROP TABLE gin_check;
22+
-- Test index inserts
23+
SELECT setseed(1);
24+
setseed
25+
---------
26+
27+
(1 row)
28+
29+
CREATE TABLE "gin_check"("Column1" int[]);
30+
CREATE INDEX gin_check_idx on "gin_check" USING GIN("Column1");
31+
ALTER INDEX gin_check_idx SET (fastupdate = false);
32+
-- posting trees
33+
INSERT INTO gin_check select array_agg(round(random()*255) ) from generate_series(1, 100000) as i group by i % 10000;
34+
-- posting leaves
35+
INSERT INTO gin_check select array_agg(100 + round(random()*255)) from generate_series(1, 100) as i group by i % 100;
36+
SELECT gin_index_check('gin_check_idx');
37+
gin_index_check
38+
-----------------
39+
40+
(1 row)
41+
42+
-- cleanup
43+
DROP TABLE gin_check;
44+
-- Test GIN over text array
45+
SELECT setseed(1);
46+
setseed
47+
---------
48+
49+
(1 row)
50+
51+
CREATE TABLE "gin_check_text_array"("Column1" text[]);
52+
-- posting trees
53+
INSERT INTO gin_check_text_array select array_agg(md5(round(random()*300)::text)::text) from generate_series(1, 100000) as i group by i % 10000;
54+
-- posting leaves
55+
INSERT INTO gin_check_text_array select array_agg(md5(round(random()*300 + 300)::text)::text) from generate_series(1, 10000) as i group by i % 100;
56+
CREATE INDEX gin_check_text_array_idx on "gin_check_text_array" USING GIN("Column1");
57+
SELECT gin_index_check('gin_check_text_array_idx');
58+
gin_index_check
59+
-----------------
60+
61+
(1 row)
62+
63+
-- cleanup
64+
DROP TABLE gin_check_text_array;
65+
-- Test GIN over jsonb
66+
CREATE TABLE "gin_check_jsonb"("j" jsonb);
67+
INSERT INTO gin_check_jsonb values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
68+
INSERT INTO gin_check_jsonb values ('[[14,2,3]]');
69+
INSERT INTO gin_check_jsonb values ('[1,[14,2,3]]');
70+
CREATE INDEX "gin_check_jsonb_idx" on gin_check_jsonb USING GIN("j" jsonb_path_ops);
71+
SELECT gin_index_check('gin_check_jsonb_idx');
72+
gin_index_check
73+
-----------------
74+
75+
(1 row)
76+
77+
-- cleanup
78+
DROP TABLE gin_check_jsonb;

contrib/amcheck/meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Copyright (c) 2022-2025, PostgreSQL Global Development Group
22

33
amcheck_sources = files(
4+
'verify_common.c',
5+
'verify_gin.c',
46
'verify_heapam.c',
57
'verify_nbtree.c',
68
)
@@ -24,6 +26,7 @@ install_data(
2426
'amcheck--1.1--1.2.sql',
2527
'amcheck--1.2--1.3.sql',
2628
'amcheck--1.3--1.4.sql',
29+
'amcheck--1.4--1.5.sql',
2730
kwargs: contrib_data_args,
2831
)
2932

@@ -35,6 +38,7 @@ tests += {
3538
'sql': [
3639
'check',
3740
'check_btree',
41+
'check_gin',
3842
'check_heap',
3943
],
4044
},

contrib/amcheck/sql/check_gin.sql

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
-- Test of index bulk load
2+
SELECT setseed(1);
3+
CREATE TABLE "gin_check"("Column1" int[]);
4+
-- posting trees (frequently used entries)
5+
INSERT INTO gin_check select array_agg(round(random()*255) ) from generate_series(1, 100000) as i group by i % 10000;
6+
-- posting leaves (sparse entries)
7+
INSERT INTO gin_check select array_agg(255 + round(random()*100)) from generate_series(1, 100) as i group by i % 100;
8+
CREATE INDEX gin_check_idx on "gin_check" USING GIN("Column1");
9+
SELECT gin_index_check('gin_check_idx');
10+
11+
-- cleanup
12+
DROP TABLE gin_check;
13+
14+
-- Test index inserts
15+
SELECT setseed(1);
16+
CREATE TABLE "gin_check"("Column1" int[]);
17+
CREATE INDEX gin_check_idx on "gin_check" USING GIN("Column1");
18+
ALTER INDEX gin_check_idx SET (fastupdate = false);
19+
-- posting trees
20+
INSERT INTO gin_check select array_agg(round(random()*255) ) from generate_series(1, 100000) as i group by i % 10000;
21+
-- posting leaves
22+
INSERT INTO gin_check select array_agg(100 + round(random()*255)) from generate_series(1, 100) as i group by i % 100;
23+
24+
SELECT gin_index_check('gin_check_idx');
25+
26+
-- cleanup
27+
DROP TABLE gin_check;
28+
29+
-- Test GIN over text array
30+
SELECT setseed(1);
31+
CREATE TABLE "gin_check_text_array"("Column1" text[]);
32+
-- posting trees
33+
INSERT INTO gin_check_text_array select array_agg(md5(round(random()*300)::text)::text) from generate_series(1, 100000) as i group by i % 10000;
34+
-- posting leaves
35+
INSERT INTO gin_check_text_array select array_agg(md5(round(random()*300 + 300)::text)::text) from generate_series(1, 10000) as i group by i % 100;
36+
CREATE INDEX gin_check_text_array_idx on "gin_check_text_array" USING GIN("Column1");
37+
SELECT gin_index_check('gin_check_text_array_idx');
38+
39+
-- cleanup
40+
DROP TABLE gin_check_text_array;
41+
42+
-- Test GIN over jsonb
43+
CREATE TABLE "gin_check_jsonb"("j" jsonb);
44+
INSERT INTO gin_check_jsonb values ('{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
45+
INSERT INTO gin_check_jsonb values ('[[14,2,3]]');
46+
INSERT INTO gin_check_jsonb values ('[1,[14,2,3]]');
47+
CREATE INDEX "gin_check_jsonb_idx" on gin_check_jsonb USING GIN("j" jsonb_path_ops);
48+
49+
SELECT gin_index_check('gin_check_jsonb_idx');
50+
51+
-- cleanup
52+
DROP TABLE gin_check_jsonb;

contrib/amcheck/t/002_cic.pl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
'lock_timeout = ' . (1000 * $PostgreSQL::Test::Utils::timeout_default));
2222
$node->start;
2323
$node->safe_psql('postgres', q(CREATE EXTENSION amcheck));
24-
$node->safe_psql('postgres', q(CREATE TABLE tbl(i int)));
24+
$node->safe_psql('postgres', q(CREATE TABLE tbl(i int, j jsonb)));
2525
$node->safe_psql('postgres', q(CREATE INDEX idx ON tbl(i)));
26+
$node->safe_psql('postgres', q(CREATE INDEX ginidx ON tbl USING gin(j)));
2627

2728
#
2829
# Stress CIC with pgbench.
@@ -40,21 +41,24 @@
4041
{
4142
'002_pgbench_concurrent_transaction' => q(
4243
BEGIN;
43-
INSERT INTO tbl VALUES(0);
44+
INSERT INTO tbl VALUES(0, '{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
4445
COMMIT;
4546
),
4647
'002_pgbench_concurrent_transaction_savepoints' => q(
4748
BEGIN;
4849
SAVEPOINT s1;
49-
INSERT INTO tbl VALUES(0);
50+
INSERT INTO tbl VALUES(0, '[[14,2,3]]');
5051
COMMIT;
5152
),
5253
'002_pgbench_concurrent_cic' => q(
5354
SELECT pg_try_advisory_lock(42)::integer AS gotlock \gset
5455
\if :gotlock
5556
DROP INDEX CONCURRENTLY idx;
5657
CREATE INDEX CONCURRENTLY idx ON tbl(i);
58+
DROP INDEX CONCURRENTLY ginidx;
59+
CREATE INDEX CONCURRENTLY ginidx ON tbl USING gin(j);
5760
SELECT bt_index_check('idx',true);
61+
SELECT gin_index_check('ginidx');
5862
SELECT pg_advisory_unlock(42);
5963
\endif
6064
)

contrib/amcheck/t/003_cic_2pc.pl

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
'lock_timeout = ' . (1000 * $PostgreSQL::Test::Utils::timeout_default));
2626
$node->start;
2727
$node->safe_psql('postgres', q(CREATE EXTENSION amcheck));
28-
$node->safe_psql('postgres', q(CREATE TABLE tbl(i int)));
28+
$node->safe_psql('postgres', q(CREATE TABLE tbl(i int, j jsonb)));
2929

3030

3131
#
@@ -41,7 +41,7 @@
4141
$main_h->query_safe(
4242
q(
4343
BEGIN;
44-
INSERT INTO tbl VALUES(0);
44+
INSERT INTO tbl VALUES(0, '[[14,2,3]]');
4545
));
4646

4747
my $cic_h = $node->background_psql('postgres');
@@ -50,6 +50,7 @@
5050
qr/start/, q(
5151
\echo start
5252
CREATE INDEX CONCURRENTLY idx ON tbl(i);
53+
CREATE INDEX CONCURRENTLY ginidx ON tbl USING gin(j);
5354
));
5455

5556
$main_h->query_safe(
@@ -60,7 +61,7 @@
6061
$main_h->query_safe(
6162
q(
6263
BEGIN;
63-
INSERT INTO tbl VALUES(0);
64+
INSERT INTO tbl VALUES(0, '[[14,2,3]]');
6465
));
6566

6667
$node->safe_psql('postgres', q(COMMIT PREPARED 'a';));
@@ -69,7 +70,7 @@
6970
q(
7071
PREPARE TRANSACTION 'b';
7172
BEGIN;
72-
INSERT INTO tbl VALUES(0);
73+
INSERT INTO tbl VALUES(0, '"mary had a little lamb"');
7374
));
7475

7576
$node->safe_psql('postgres', q(COMMIT PREPARED 'b';));
@@ -86,6 +87,9 @@
8687
$result = $node->psql('postgres', q(SELECT bt_index_check('idx',true)));
8788
is($result, '0', 'bt_index_check after overlapping 2PC');
8889

90+
$result = $node->psql('postgres', q(SELECT gin_index_check('ginidx')));
91+
is($result, '0', 'gin_index_check after overlapping 2PC');
92+
8993

9094
#
9195
# Server restart shall not change whether prepared xact blocks CIC
@@ -94,7 +98,7 @@
9498
$node->safe_psql(
9599
'postgres', q(
96100
BEGIN;
97-
INSERT INTO tbl VALUES(0);
101+
INSERT INTO tbl VALUES(0, '{"a":[["b",{"x":1}],["b",{"x":2}]],"c":3}');
98102
PREPARE TRANSACTION 'spans_restart';
99103
BEGIN;
100104
CREATE TABLE unused ();
@@ -108,12 +112,16 @@
108112
\echo start
109113
DROP INDEX CONCURRENTLY idx;
110114
CREATE INDEX CONCURRENTLY idx ON tbl(i);
115+
DROP INDEX CONCURRENTLY ginidx;
116+
CREATE INDEX CONCURRENTLY ginidx ON tbl USING gin(j);
111117
));
112118

113119
$node->safe_psql('postgres', "COMMIT PREPARED 'spans_restart'");
114120
$reindex_h->quit;
115121
$result = $node->psql('postgres', q(SELECT bt_index_check('idx',true)));
116122
is($result, '0', 'bt_index_check after 2PC and restart');
123+
$result = $node->psql('postgres', q(SELECT gin_index_check('ginidx')));
124+
is($result, '0', 'gin_index_check after 2PC and restart');
117125

118126

119127
#
@@ -136,14 +144,14 @@
136144
{
137145
'003_pgbench_concurrent_2pc' => q(
138146
BEGIN;
139-
INSERT INTO tbl VALUES(0);
147+
INSERT INTO tbl VALUES(0,'null');
140148
PREPARE TRANSACTION 'c:client_id';
141149
COMMIT PREPARED 'c:client_id';
142150
),
143151
'003_pgbench_concurrent_2pc_savepoint' => q(
144152
BEGIN;
145153
SAVEPOINT s1;
146-
INSERT INTO tbl VALUES(0);
154+
INSERT INTO tbl VALUES(0,'[false, "jnvaba", -76, 7, {"_": [1]}, 9]');
147155
PREPARE TRANSACTION 'c:client_id';
148156
COMMIT PREPARED 'c:client_id';
149157
),
@@ -163,7 +171,25 @@
163171
SELECT bt_index_check('idx',true);
164172
SELECT pg_advisory_unlock(42);
165173
\endif
174+
),
175+
'005_pgbench_concurrent_cic' => q(
176+
SELECT pg_try_advisory_lock(42)::integer AS gotginlock \gset
177+
\if :gotginlock
178+
DROP INDEX CONCURRENTLY ginidx;
179+
CREATE INDEX CONCURRENTLY ginidx ON tbl USING gin(j);
180+
SELECT gin_index_check('ginidx');
181+
SELECT pg_advisory_unlock(42);
182+
\endif
183+
),
184+
'006_pgbench_concurrent_ric' => q(
185+
SELECT pg_try_advisory_lock(42)::integer AS gotginlock \gset
186+
\if :gotginlock
187+
REINDEX INDEX CONCURRENTLY ginidx;
188+
SELECT gin_index_check('ginidx');
189+
SELECT pg_advisory_unlock(42);
190+
\endif
166191
)
192+
167193
});
168194

169195
$node->stop;

0 commit comments

Comments
 (0)