From 4cf381e8ad3604c00c2e506bc89d2fa46625df63 Mon Sep 17 00:00:00 2001 From: Baji Shaik Date: Fri, 12 Jun 2026 17:30:47 -0500 Subject: [PATCH 3/3] Fix uuidv7() with far-future interval silently overflowing 48-bit timestamp uuidv7(interval) with a large positive interval that pushes the timestamp beyond approximately year 10889 silently produces a UUID with a truncated timestamp. The UUID version 7 timestamp field is 48 bits wide; when the millisecond value exceeds 2^48, the upper bits are silently discarded, and the resulting UUID breaks sort ordering. Fix by rejecting timestamps that would overflow the 48-bit field. --- src/backend/utils/adt/uuid.c | 11 +++++++++++ src/test/regress/expected/uuid.out | 4 ++++ src/test/regress/sql/uuid.sql | 3 +++ 3 files changed, 18 insertions(+) diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index 3269bfd922c..4bec3de1ad2 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -712,6 +712,17 @@ uuidv7_interval(PG_FUNCTION_ARGS) errmsg("timestamp out of range for UUID version 7"), errdetail("UUID version 7 does not support timestamps before the Unix epoch."))); + /* + * The UUID version 7 timestamp field is 48 bits wide, storing + * milliseconds since the Unix epoch. Reject timestamps that would + * overflow this field (dates beyond approximately year 10889). + */ + if (us / US_PER_MS > (int64) 0xFFFFFFFFFFFF) + 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 timestamps beyond approximately year 10889."))); + /* Generate an UUIDv7 */ uuid = generate_uuidv7(us / US_PER_MS, (us % US_PER_MS) * NS_PER_US + ns % NS_PER_US); diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out index 17693f20639..589f0b6ea42 100644 --- a/src/test/regress/expected/uuid.out +++ b/src/test/regress/expected/uuid.out @@ -329,6 +329,10 @@ 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. +-- uuidv7(interval) rejects timestamps that overflow the 48-bit field +SELECT uuidv7('8920 years'::interval); +ERROR: timestamp out of range for UUID version 7 +DETAIL: UUID version 7 does not support timestamps beyond approximately year 10889. -- 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 e88696ee793..3fcc68110bf 100644 --- a/src/test/regress/sql/uuid.sql +++ b/src/test/regress/sql/uuid.sql @@ -162,6 +162,9 @@ SELECT uuidv7('-1000 years'::interval); SELECT uuidv7('infinity'::interval); SELECT uuidv7('-infinity'::interval); +-- uuidv7(interval) rejects timestamps that overflow the 48-bit field +SELECT uuidv7('8920 years'::interval); + -- casts SELECT '5b35380a-7143-4912-9b55-f322699c6770'::uuid::bytea; SELECT '\x019a2f859ced7225b99d9c55044a2563'::bytea::uuid; -- 2.50.1 (Apple Git-155)