From f66cde033f024403227c1d036dee410f3fe62a16 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <amborodin@acm.org>
Date: Fri, 29 Nov 2024 23:04:57 +0500
Subject: [PATCH v41 2/3] Fixes to address review notes by Peter Eisentraut

---
 doc/src/sgml/func.sgml                   | 13 ++++++++-----
 src/backend/utils/adt/uuid.c             | 18 ++++++++++++------
 src/include/catalog/pg_proc.dat          | 12 ++++++------
 src/test/regress/expected/opr_sanity.out |  1 -
 src/test/regress/expected/uuid.out       |  8 ++++----
 src/test/regress/sql/uuid.sql            |  8 ++++----
 6 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index e9a2db2e93..bf3a304134 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -14279,10 +14279,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
 </synopsis>
    These functions return a version 4 (random) UUID.
 <synopsis>
-<function>uuidv7</function> () <returnvalue>uuid</returnvalue>
+<function>uuidv7</function> (<optional> <parameter>shift</parameter> <type>interval</type> </optional>) <returnvalue>uuid</returnvalue>
 </synopsis>
     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 <parameter>shift</parameter> parameter of type <type>interval</type>
+    which shift internal timestamp by the given interval.
   </para>
 
   <para>
@@ -14296,9 +14298,10 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
 <function>uuid_extract_timestamp</function> (uuid) <returnvalue>timestamp with time zone</returnvalue>
 </synopsis>
    This function extracts a <type>timestamp with time zone</type> from UUID
-   version 1.  For other versions, this function returns null.  Note that the
-   extracted timestamp is not necessarily exactly equal to the time the UUID
-   was generated; this depends on the implementation that generated the UUID.
+   version 1 and 7.  For other versions, this function returns null.  Note that
+   the extracted timestamp is not necessarily exactly equal to the time the
+   UUID was generated; this depends on the implementation that generated the
+   UUID.
   </para>
 
   <para>
diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c
index bb890e9f60..b09297449a 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)
 {
@@ -520,6 +522,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 +597,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 +616,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..a218c3e22b 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -9342,14 +9342,14 @@
 { oid => '3432', descr => 'generate random UUID',
   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',
+{ oid => '9895', descr => 'generate UUID version 4', proleakproof => 't',
+  proname => 'uuidv4', provolatile => 'v',
   prorettype => 'uuid', proargtypes => '', prosrc => 'gen_random_uuid' },
-{ oid => '9896', descr => 'generate UUID version 7',
-  proname => 'uuidv7', proleakproof => 't', provolatile => 'v',
+{ oid => '9896', descr => 'generate UUID version 7', proleakproof => 't',
+  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..2a9e15b39b 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -880,7 +880,6 @@ 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)

