Re: BRIN minmax multi - incorrect distance for infinite timestamp/date
Tomas Vondra <tomas.vondra@enterprisedb.com>
From: Tomas Vondra <tomas.vondra@enterprisedb.com>
To: Dean Rasheed <dean.a.rasheed@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>,
Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: 2023-10-13T10:44:38Z
Lists: pgsql-hackers
Attachments
- brin-infinity-fix-v2.patch (text/x-patch) patch v2
On 10/13/23 11:21, Dean Rasheed wrote:
> On Thu, 12 Oct 2023 at 23:43, Tomas Vondra
> <tomas.vondra@enterprisedb.com> wrote:
>>
>> Ashutosh Bapat reported me off-list a possible issue in how BRIN
>> minmax-multi calculate distance for infinite timestamp/date values.
>>
>> The current code does this:
>>
>> if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2))
>> PG_RETURN_FLOAT8(0);
>>
>
> Yes indeed, that looks wrong. I noticed the same thing while reviewing
> the infinite interval patch.
>
>> so means infinite values are "very close" to any other value, and thus
>> likely to be merged into a summary range. That's exactly the opposite of
>> what we want to do, possibly resulting in inefficient indexes.
>>
>
> Is this only inefficient? Or can it also lead to wrong query results?
>
I don't think it can produce incorrect results. It only affects which
values we "merge" into an interval when building the summaries.
>> Attached is a patch fixing this
>>
>
> I wonder if it's actually necessary to give infinity any special
> handling at all for dates and timestamps. For those types, "infinity"
> is actually just INT_MIN/MAX, which compares correctly with any finite
> value, and will be much larger/smaller than any common value, so it
> seems like it isn't necessary to give "infinite" values any special
> treatment. That would be consistent with date_cmp() and
> timestamp_cmp().
>
Right, but ....
> Something else that looks wrong about that BRIN code is that the
> integer subtraction might lead to overflow -- it is subtracting two
> integer values, then casting the result to float8. It should cast each
> input before subtracting, more like brin_minmax_multi_distance_int8().
>
... it also needs to fix this, otherwise it overflows. Consider
delta = dt2 - dt1;
and assume dt1 is INT64_MIN, or that dt2 is INT64_MAX.
> IOW, I think brin_minmax_multi_distance_date/timestamp could be made
> basically identical to brin_minmax_multi_distance_int4/8.
>
Right. Attached is a patch doing it this way.
regards
--
Tomas Vondra
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
Commits
-
Fix minmax-multi distance for extreme interval values
- 0fa73c5cd050 14.10 landed
- 2fbb2fcb0c63 15.5 landed
- 924e0e2ee058 16.1 landed
- c6cf6d353c28 17.0 landed
-
Fix minmax-multi on infinite date/timestamp values
- 52c934cc1f2e 14.10 landed
- d04a9283b707 15.5 landed
- 497fc92086f8 16.1 landed
- 8da86d62a112 17.0 landed
-
Fix calculation in brin_minmax_multi_distance_date
- d1740e169d95 14.10 landed
- 088233f8db6c 15.5 landed
- e7965226d551 16.1 landed
- 394d51731495 17.0 landed
-
Fix overflow when calculating timestamp distance in BRIN
- 90c4da6d4392 14.10 landed
- daa7b0d7ce14 15.5 landed
- 0635fe02b426 16.1 landed
- b5489b75c6ce 17.0 landed