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

Appearance settings

Commit d91353f

Browse filesBrowse files
committed
Fix handling of NaN values in BRIN minmax multi
When calculating distance between float4/float8 values, we need to be a bit more careful about NaN values in order not to trigger assert. We consider NaN values to be equal (distace 0.0) and in infinite distance from all other values. On builds without asserts, this issue is mostly harmless - the ranges may be merged in less efficient order, but the index is still correct. Per report from Andreas Seltenreich. Backpatch to 14, where this new BRIN opclass was introduced. Reported-by: Andreas Seltenreich Discussion: https://postgr.es/m/87r1bw9ukm.fsf@credativ.de
1 parent f214960 commit d91353f
Copy full SHA for d91353f

File tree

3 files changed

+24
-0
lines changed
Filter options

3 files changed

+24
-0
lines changed

‎src/backend/access/brin/brin_minmax_multi.c

Copy file name to clipboardExpand all lines: src/backend/access/brin/brin_minmax_multi.c
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "utils/builtins.h"
7474
#include "utils/date.h"
7575
#include "utils/datum.h"
76+
#include "utils/float.h"
7677
#include "utils/inet.h"
7778
#include "utils/lsyscache.h"
7879
#include "utils/memutils.h"
@@ -1872,6 +1873,14 @@ brin_minmax_multi_distance_float4(PG_FUNCTION_ARGS)
18721873
float a1 = PG_GETARG_FLOAT4(0);
18731874
float a2 = PG_GETARG_FLOAT4(1);
18741875

1876+
/* if both values are NaN, then we consider them the same */
1877+
if (isnan(a1) && isnan(a2))
1878+
PG_RETURN_FLOAT8(0.0);
1879+
1880+
/* if one value is NaN, use infinite distance */
1881+
if (isnan(a1) || isnan(a2))
1882+
PG_RETURN_FLOAT8(get_float8_infinity());
1883+
18751884
/*
18761885
* We know the values are range boundaries, but the range may be collapsed
18771886
* (i.e. single points), with equal values.
@@ -1890,6 +1899,14 @@ brin_minmax_multi_distance_float8(PG_FUNCTION_ARGS)
18901899
double a1 = PG_GETARG_FLOAT8(0);
18911900
double a2 = PG_GETARG_FLOAT8(1);
18921901

1902+
/* if both values are NaN, then we consider them the same */
1903+
if (isnan(a1) && isnan(a2))
1904+
PG_RETURN_FLOAT8(0.0);
1905+
1906+
/* if one value is NaN, use infinite distance */
1907+
if (isnan(a1) || isnan(a2))
1908+
PG_RETURN_FLOAT8(get_float8_infinity());
1909+
18931910
/*
18941911
* We know the values are range boundaries, but the range may be collapsed
18951912
* (i.e. single points), with equal values.

‎src/test/regress/expected/brin_multi.out

Copy file name to clipboardExpand all lines: src/test/regress/expected/brin_multi.out
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ SELECT brin_desummarize_range('brinidx_multi', 0);
347347
(1 row)
348348

349349
VACUUM brintest_multi; -- force a summarization cycle in brinidx
350+
-- Try inserting a values with NaN, to test distance calculation.
351+
insert into public.brintest_multi (float4col) values (real 'nan');
352+
insert into public.brintest_multi (float8col) values (real 'nan');
350353
UPDATE brintest_multi SET int8col = int8col * int4col;
351354
-- Tests for brin_summarize_new_values
352355
SELECT brin_summarize_new_values('brintest_multi'); -- error, not an index

‎src/test/regress/sql/brin_multi.sql

Copy file name to clipboardExpand all lines: src/test/regress/sql/brin_multi.sql
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,10 @@ FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5;
351351
SELECT brin_desummarize_range('brinidx_multi', 0);
352352
VACUUM brintest_multi; -- force a summarization cycle in brinidx
353353

354+
-- Try inserting a values with NaN, to test distance calculation.
355+
insert into public.brintest_multi (float4col) values (real 'nan');
356+
insert into public.brintest_multi (float8col) values (real 'nan');
357+
354358
UPDATE brintest_multi SET int8col = int8col * int4col;
355359

356360
-- Tests for brin_summarize_new_values

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.