From a7720773eb27f821d603f8aba2cff6453d0797a3 Mon Sep 17 00:00:00 2001 From: Andrey Borodin Date: Fri, 29 Nov 2024 23:04:57 +0500 Subject: [PATCH v40 2/2] Fixes to address review notes by Peter Eisentraut --- doc/src/sgml/func.sgml | 4 +++- src/backend/utils/adt/uuid.c | 27 ++++++++++++++++++------ src/include/catalog/pg_proc.dat | 10 ++++----- src/test/regress/expected/opr_sanity.out | 3 --- src/test/regress/expected/uuid.out | 8 +++---- src/test/regress/sql/uuid.sql | 8 +++---- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index e9a2db2e93..f992d5266c 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -14282,7 +14282,9 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple uuidv7 () uuid This function returns a version 7 UUID (UNIX timestamp with millisecond - precision + sub-millisecond timestamp + random). + precision + sub-millisecond timestamp + random). This function can accept + optional shift parameter of type interval + which shift internal timestamp by the given interval. diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index bb890e9f60..e962f85838 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -433,7 +433,9 @@ uuid_hash_extended(PG_FUNCTION_ARGS) return hash_any_extended(key->data, UUID_LEN, PG_GETARG_INT64(1)); } -/* Set the given UUID version and the variant bits */ +/* + * Set the given UUID version and the variant bits + */ static inline void uuid_set_version(pg_uuid_t *uuid, unsigned char version) { @@ -469,6 +471,15 @@ gen_random_uuid(PG_FUNCTION_ARGS) PG_RETURN_UUID_P(uuid); } +/* + * Wrapper for gen_random_uuid() + */ +Datum +uuidv4(PG_FUNCTION_ARGS) +{ + return gen_random_uuid(fcinfo); +} + /* * Get the current timestamp with nanosecond precision for UUID generation. * The returned timestamp is ensured to be at least SUBMS_MINIMAL_STEP greater @@ -520,6 +531,9 @@ get_real_time_ns_ascending() * method "Replace Leftmost Random Bits with Increased Clock Precision (Method 3)". * This method utilizes 12 bits from the "rand_a" bits to store a 1/4096 * (or 2^12) fraction of sub-millisecond precision. + * + * ns is a number of nanoseconds since start of the UNIX epoch. This value is + * used for time-dependent bits of UUID. */ static pg_attribute_always_inline pg_uuid_t * generate_uuidv7(int64 ns) @@ -592,16 +606,17 @@ uuidv7(PG_FUNCTION_ARGS) Datum uuidv7_interval(PG_FUNCTION_ARGS) { - Interval *span = PG_GETARG_INTERVAL_P(0); + Interval *shift = PG_GETARG_INTERVAL_P(0); TimestampTz ts; pg_uuid_t *uuid; int64 ns = get_real_time_ns_ascending(); /* - * Shift the current timestamp by the given interval. To make correct - * calculating the time shift, we convert the UNIX epoch to TimestampTz + * Shift the current timestamp by the given interval. To calsulate time + * shift correctly, we convert the UNIX epoch to TimestampTz * and use timestamptz_pl_interval(). Since this calculation is done with - * microsecond precision, we carry back the nanoseconds. + * microsecond precision, we carry nanoseconds from original ns value to + * shifted ns value. */ ts = (TimestampTz) (ns / NS_PER_US) - @@ -610,7 +625,7 @@ uuidv7_interval(PG_FUNCTION_ARGS) /* Compute time shift */ ts = DatumGetTimestampTz(DirectFunctionCall2(timestamptz_pl_interval, TimestampTzGetDatum(ts), - IntervalPGetDatum(span))); + IntervalPGetDatum(shift))); /* * Convert a TimestampTz value back to an UNIX epoch and carry back diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3353e9d6e3..046ce3eb67 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -9343,13 +9343,13 @@ proname => 'gen_random_uuid', proleakproof => 't', provolatile => 'v', prorettype => 'uuid', proargtypes => '', prosrc => 'gen_random_uuid' }, { oid => '9895', descr => 'generate UUID version 4', - proname => 'uuidv4', proleakproof => 't', provolatile => 'v', - prorettype => 'uuid', proargtypes => '', prosrc => 'gen_random_uuid' }, + proname => 'uuidv4', provolatile => 'v', + prorettype => 'uuid', proargtypes => '', prosrc => 'uuidv4' }, { oid => '9896', descr => 'generate UUID version 7', - proname => 'uuidv7', proleakproof => 't', provolatile => 'v', + proname => 'uuidv7', provolatile => 'v', prorettype => 'uuid', proargtypes => '', prosrc => 'uuidv7' }, -{ oid => '9897', descr => 'generate UUID version 7 with a timestamp shifted on specific interval', - proname => 'uuidv7', proleakproof => 't', provolatile => 'v', +{ oid => '9897', descr => 'generate UUID version 7 with a timestamp shifted by specific interval', + proname => 'uuidv7', provolatile => 'v', proargnames => '{shift}', prorettype => 'uuid', proargtypes => 'interval', prosrc => 'uuidv7_interval' }, { oid => '6342', descr => 'extract timestamp from UUID', proname => 'uuid_extract_timestamp', proleakproof => 't', diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 43e7180a16..34a32bd11d 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -878,9 +878,6 @@ crc32(bytea) crc32c(bytea) bytea_larger(bytea,bytea) bytea_smaller(bytea,bytea) -uuidv4() -uuidv7() -uuidv7(interval) -- restore normal output mode \a\t -- List of functions used by libpq's fe-lobj.c diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out index 0059a8c716..798633ad51 100644 --- a/src/test/regress/expected/uuid.out +++ b/src/test/regress/expected/uuid.out @@ -253,26 +253,26 @@ SELECT uuid_extract_version('11111111-1111-1111-1111-111111111111'); -- null (1 row) -SELECT uuid_extract_version(uuidv4()); --4 +SELECT uuid_extract_version(uuidv4()); -- 4 uuid_extract_version ---------------------- 4 (1 row) -SELECT uuid_extract_version(uuidv7()); --7 +SELECT uuid_extract_version(uuidv7()); -- 7 uuid_extract_version ---------------------- 7 (1 row) -- timestamp -SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v1 +SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v1 ?column? ---------- t (1 row) -SELECT uuid_extract_timestamp('017F22E2-79B0-7CC3-98C4-DC0C0C07398F') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v7 +SELECT uuid_extract_timestamp('017F22E2-79B0-7CC3-98C4-DC0C0C07398F') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v7 ?column? ---------- t diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql index 6eb8efbd3d..110188361d 100644 --- a/src/test/regress/sql/uuid.sql +++ b/src/test/regress/sql/uuid.sql @@ -125,12 +125,12 @@ SELECT array_agg(id ORDER BY guid_field) FROM guid3; SELECT uuid_extract_version('11111111-1111-5111-8111-111111111111'); -- 5 SELECT uuid_extract_version(gen_random_uuid()); -- 4 SELECT uuid_extract_version('11111111-1111-1111-1111-111111111111'); -- null -SELECT uuid_extract_version(uuidv4()); --4 -SELECT uuid_extract_version(uuidv7()); --7 +SELECT uuid_extract_version(uuidv4()); -- 4 +SELECT uuid_extract_version(uuidv7()); -- 7 -- timestamp -SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v1 -SELECT uuid_extract_timestamp('017F22E2-79B0-7CC3-98C4-DC0C0C07398F') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v7 +SELECT uuid_extract_timestamp('C232AB00-9414-11EC-B3C8-9F6BDECED846') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v1 +SELECT uuid_extract_timestamp('017F22E2-79B0-7CC3-98C4-DC0C0C07398F') = 'Tuesday, February 22, 2022 2:22:22.00 PM GMT+05:00'; -- RFC 9562 test vector for v7 SELECT uuid_extract_timestamp(gen_random_uuid()); -- null SELECT uuid_extract_timestamp('11111111-1111-1111-1111-111111111111'); -- null -- 2.39.5 (Apple Git-154)