From 620b2a4398e2820b8b750d99f41d75b45066e2ff Mon Sep 17 00:00:00 2001 From: Baji Shaik Date: Wed, 24 Jun 2026 18:08:44 -0500 Subject: [PATCH v2 3/3] Reject timestamps beyond 48-bit limit in uuidv7(interval) uuidv7() with a large positive interval silently produced UUIDs whose timestamp overflowed the 48-bit field, wrapping around and producing incorrect time-ordering. UUID version 7's timestamp field can represent dates up to approximately 10889-08-02 05:31:50.655 UTC. Reject shifted timestamps that exceed this maximum. Use INT64CONST() for the 48-bit constant. Author: Baji Shaik Discussion: https://postgr.es/m/18F007D6-1A33-48C8-BA51-E7A858DE0C89%40thebuild.com --- src/backend/utils/adt/uuid.c | 7 +++++++ src/test/regress/expected/uuid.out | 4 ++++ src/test/regress/sql/uuid.sql | 3 +++ 3 files changed, 14 insertions(+) diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index ca5dbca8ac3..5fa7cd72761 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -715,6 +715,13 @@ 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 (1970-01-01 00:00:00 UTC)."))); + /* Reject timestamps beyond the 48-bit millisecond field maximum */ + if (us / US_PER_MS > (INT64CONST(1) << 48) - 1) + 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 72730825cda..1fe95454dcf 100644 --- a/src/test/regress/expected/uuid.out +++ b/src/test/regress/expected/uuid.out @@ -276,6 +276,10 @@ DETAIL: UUID version 7 does not support timestamps before the Unix epoch (1970- SELECT uuidv7('292230 years'::interval); ERROR: timestamp out of range for UUID version 7 DETAIL: The shifted timestamp overflows the representable range. +-- uuidv7: timestamps beyond 48-bit ms field (~year 10889) are rejected +SELECT uuidv7('9000 years'::interval); +ERROR: timestamp out of range for UUID version 7 +DETAIL: UUID version 7 does not support timestamps beyond approximately year 10889. -- extract functions -- version SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111'); -- 5 diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql index eb1a12949c5..2bd2fc51620 100644 --- a/src/test/regress/sql/uuid.sql +++ b/src/test/regress/sql/uuid.sql @@ -150,6 +150,9 @@ SELECT uuidv7('-1000 years'::interval); -- uuidv7: large future intervals that overflow epoch conversion are rejected SELECT uuidv7('292230 years'::interval); +-- uuidv7: timestamps beyond 48-bit ms field (~year 10889) are rejected +SELECT uuidv7('9000 years'::interval); + -- extract functions -- version -- 2.50.1 (Apple Git-155)