From fd0656023b900e73475cccad255ffef7d472e00f Mon Sep 17 00:00:00 2001 From: Baji Shaik Date: Fri, 12 Jun 2026 17:30:24 -0500 Subject: [PATCH 2/3] Fix uuidv7() with infinite interval causing integer overflow uuidv7('infinity'::interval) overflows int64 during the epoch conversion and produces a UUID with an incorrect timestamp. Fix by adding a TIMESTAMP_NOT_FINITE check after timestamptz_pl_interval(), which catches both infinity and -infinity before any arithmetic on the timestamp value. --- src/backend/utils/adt/uuid.c | 11 +++++++++++ src/test/regress/expected/uuid.out | 7 +++++++ src/test/regress/sql/uuid.sql | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index c44858b6391..3269bfd922c 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -687,6 +687,17 @@ uuidv7_interval(PG_FUNCTION_ARGS) TimestampTzGetDatum(ts), IntervalPGetDatum(shift))); + /* + * Reject infinite intervals. timestamptz_pl_interval() can produce an + * infinite timestamp when the input interval is infinite, and converting + * that to a Unix epoch value would overflow. + */ + if (TIMESTAMP_NOT_FINITE(ts)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamp out of range for UUID version 7"), + errdetail("UUID version 7 does not support infinite timestamps."))); + /* Convert a TimestampTz value back to an UNIX epoch timestamp */ us = ts + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY * USECS_PER_SEC; diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out index ea3c1adf412..17693f20639 100644 --- a/src/test/regress/expected/uuid.out +++ b/src/test/regress/expected/uuid.out @@ -322,6 +322,13 @@ SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111'); -- null SELECT uuidv7('-1000 years'::interval); ERROR: timestamp out of range for UUID version 7 DETAIL: UUID version 7 does not support timestamps before the Unix epoch. +-- uuidv7(interval) rejects infinite intervals +SELECT uuidv7('infinity'::interval); +ERROR: timestamp out of range for UUID version 7 +DETAIL: UUID version 7 does not support infinite timestamps. +SELECT uuidv7('-infinity'::interval); +ERROR: timestamp out of range for UUID version 7 +DETAIL: UUID version 7 does not support infinite timestamps. -- casts SELECT '5b35380a-7143-4912-9b55-f322699c6770'::uuid::bytea; bytea diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql index 15442f5f9e7..e88696ee793 100644 --- a/src/test/regress/sql/uuid.sql +++ b/src/test/regress/sql/uuid.sql @@ -158,6 +158,10 @@ SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111'); -- null -- uuidv7(interval) rejects timestamps before the Unix epoch SELECT uuidv7('-1000 years'::interval); +-- uuidv7(interval) rejects infinite intervals +SELECT uuidv7('infinity'::interval); +SELECT uuidv7('-infinity'::interval); + -- casts SELECT '5b35380a-7143-4912-9b55-f322699c6770'::uuid::bytea; SELECT '\x019a2f859ced7225b99d9c55044a2563'::bytea::uuid; -- 2.50.1 (Apple Git-155)