Skip to content

Commit e858312

Browse files
committed
Fix netmask handling in inet_minmax_multi_ops
When calculating distance in brin_minmax_multi_distance_inet(), the netmask was applied incorrectly. This results in (seemingly) incorrect ordering of values, triggering an assert. For builds without asserts this is mostly harmless - we may merge other ranges, possibly resulting in slightly less efficient index. But it's still correct and the greedy algorithm doesn't guarantee optimality anyway. Backpatch to 14, where minmax-multi indexes were introduced. Reported by Dmitry Dolgov, investigation and fix by me. Reported-by: Dmitry Dolgov Backpatch-through: 14 Discussion: https://postgr.es/m/17774-c6f3e36dd4471e67@postgresql.org
1 parent 0b51d42 commit e858312

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

src/backend/access/brin/brin_minmax_multi.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -2364,14 +2364,14 @@ brin_minmax_multi_distance_inet(PG_FUNCTION_ARGS)
23642364
unsigned char mask;
23652365
int nbits;
23662366

2367-
nbits = lena - (i * 8);
2367+
nbits = Max(0, lena - (i * 8));
23682368
if (nbits < 8)
23692369
{
23702370
mask = (0xFF << (8 - nbits));
23712371
addra[i] = (addra[i] & mask);
23722372
}
23732373

2374-
nbits = lenb - (i * 8);
2374+
nbits = Max(0, lenb - (i * 8));
23752375
if (nbits < 8)
23762376
{
23772377
mask = (0xFF << (8 - nbits));

src/test/regress/expected/brin_multi.out

+6
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,12 @@ VACUUM brintest_multi; -- force a summarization cycle in brinidx
351351
insert into public.brintest_multi (float4col) values (real 'nan');
352352
insert into public.brintest_multi (float8col) values (real 'nan');
353353
UPDATE brintest_multi SET int8col = int8col * int4col;
354+
-- Test handling of inet netmasks with inet_minmax_multi_ops
355+
CREATE TABLE brin_test_inet (a inet);
356+
CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops);
357+
INSERT INTO brin_test_inet VALUES ('127.0.0.1/0');
358+
INSERT INTO brin_test_inet VALUES ('0.0.0.0/12');
359+
DROP TABLE brin_test_inet;
354360
-- Tests for brin_summarize_new_values
355361
SELECT brin_summarize_new_values('brintest_multi'); -- error, not an index
356362
ERROR: "brintest_multi" is not an index

src/test/regress/sql/brin_multi.sql

+7
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,13 @@ insert into public.brintest_multi (float8col) values (real 'nan');
357357

358358
UPDATE brintest_multi SET int8col = int8col * int4col;
359359

360+
-- Test handling of inet netmasks with inet_minmax_multi_ops
361+
CREATE TABLE brin_test_inet (a inet);
362+
CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops);
363+
INSERT INTO brin_test_inet VALUES ('127.0.0.1/0');
364+
INSERT INTO brin_test_inet VALUES ('0.0.0.0/12');
365+
DROP TABLE brin_test_inet;
366+
360367
-- Tests for brin_summarize_new_values
361368
SELECT brin_summarize_new_values('brintest_multi'); -- error, not an index
362369
SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index

0 commit comments

Comments
 (0)