btree_gin: Fix calculation of leftmost interval value.

Formerly, the value computed by leftmostvalue_interval() was a long
way short of the minimum possible interval value.  As a result, an
index scan on a GIN index on an interval column with < or <= operators
would miss large negative interval values.

Fix by setting all fields of the leftmost interval to their minimum
values, ensuring that the result is less than any other possible
interval.  Since this only affects index searches, no index rebuild is
necessary.

Back-patch to all supported branches.

Dean Rasheed, reviewed by Heikki Linnakangas.

Discussion: https://postgr.es/m/CAEZATCV80%2BgOfF8ehNUUfaKBZgZMDfCfL-g1HhWGb6kC3rpDfw%40mail.gmail.com
This commit is contained in:
Dean Rasheed 2023-10-29 11:14:37 +00:00
parent 237f8765df
commit 849172ff48
3 changed files with 17 additions and 9 deletions

View File

@ -306,9 +306,9 @@ leftmostvalue_interval(void)
{
Interval *v = palloc(sizeof(Interval));
v->time = DT_NOBEGIN;
v->day = 0;
v->month = 0;
v->time = PG_INT64_MIN;
v->day = PG_INT32_MIN;
v->month = PG_INT32_MIN;
return IntervalPGetDatum(v);
}

View File

@ -3,30 +3,34 @@ CREATE TABLE test_interval (
i interval
);
INSERT INTO test_interval VALUES
( '-178000000 years' ),
( '03:55:08' ),
( '04:55:08' ),
( '05:55:08' ),
( '08:55:08' ),
( '09:55:08' ),
( '10:55:08' )
( '10:55:08' ),
( '178000000 years' )
;
CREATE INDEX idx_interval ON test_interval USING gin (i);
SELECT * FROM test_interval WHERE i<'08:55:08'::interval ORDER BY i;
i
--------------------------
@ 178000000 years ago
@ 3 hours 55 mins 8 secs
@ 4 hours 55 mins 8 secs
@ 5 hours 55 mins 8 secs
(3 rows)
(4 rows)
SELECT * FROM test_interval WHERE i<='08:55:08'::interval ORDER BY i;
i
--------------------------
@ 178000000 years ago
@ 3 hours 55 mins 8 secs
@ 4 hours 55 mins 8 secs
@ 5 hours 55 mins 8 secs
@ 8 hours 55 mins 8 secs
(4 rows)
(5 rows)
SELECT * FROM test_interval WHERE i='08:55:08'::interval ORDER BY i;
i
@ -40,12 +44,14 @@ SELECT * FROM test_interval WHERE i>='08:55:08'::interval ORDER BY i;
@ 8 hours 55 mins 8 secs
@ 9 hours 55 mins 8 secs
@ 10 hours 55 mins 8 secs
(3 rows)
@ 178000000 years
(4 rows)
SELECT * FROM test_interval WHERE i>'08:55:08'::interval ORDER BY i;
i
---------------------------
@ 9 hours 55 mins 8 secs
@ 10 hours 55 mins 8 secs
(2 rows)
@ 178000000 years
(3 rows)

View File

@ -5,12 +5,14 @@ CREATE TABLE test_interval (
);
INSERT INTO test_interval VALUES
( '-178000000 years' ),
( '03:55:08' ),
( '04:55:08' ),
( '05:55:08' ),
( '08:55:08' ),
( '09:55:08' ),
( '10:55:08' )
( '10:55:08' ),
( '178000000 years' )
;
CREATE INDEX idx_interval ON test_interval USING gin (i);