Skip to content

Commit 5925e55

Browse files
committed
Add gen_random_uuid function
This adds a built-in function to generate UUIDs. PostgreSQL hasn't had a built-in function to generate a UUID yet, relying on external modules such as uuid-ossp and pgcrypto to provide one. Now that we have a strong random number generator built-in, we can easily provide a version 4 (random) UUID generation function. This patch takes the existing function gen_random_uuid() from pgcrypto and makes it a built-in function. The pgcrypto implementation now internally redirects to the built-in one. Reviewed-by: Fabien COELHO <coelho@cri.ensmp.fr> Discussion: https://www.postgresql.org/message-id/6a65610c-46fc-2323-6b78-e8086340a325@2ndquadrant.com
1 parent 565f339 commit 5925e55

File tree

11 files changed

+76
-34
lines changed

11 files changed

+76
-34
lines changed

contrib/pgcrypto/pgcrypto.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -446,20 +446,8 @@ PG_FUNCTION_INFO_V1(pg_random_uuid);
446446
Datum
447447
pg_random_uuid(PG_FUNCTION_ARGS)
448448
{
449-
uint8 *buf = (uint8 *) palloc(UUID_LEN);
450-
451-
/* Generate random bits. */
452-
if (!pg_strong_random(buf, UUID_LEN))
453-
px_THROW_ERROR(PXE_NO_RANDOM);
454-
455-
/*
456-
* Set magic numbers for a "version 4" (pseudorandom) UUID, see
457-
* http://tools.ietf.org/html/rfc4122#section-4.4
458-
*/
459-
buf[6] = (buf[6] & 0x0f) | 0x40; /* "version" field */
460-
buf[8] = (buf[8] & 0x3f) | 0x80; /* "variant" field */
461-
462-
PG_RETURN_UUID_P((pg_uuid_t *) buf);
449+
/* redirect to built-in function */
450+
return gen_random_uuid(fcinfo);
463451
}
464452

465453
static void *

doc/src/sgml/datatype.sgml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4195,16 +4195,8 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
41954195
</para>
41964196

41974197
<para>
4198-
<productname>PostgreSQL</productname> provides storage and comparison
4199-
functions for UUIDs, but the core database does not include any
4200-
function for generating UUIDs, because no single algorithm is well
4201-
suited for every application. The <xref
4202-
linkend="uuid-ossp"/> module
4203-
provides functions that implement several standard algorithms.
4204-
The <xref linkend="pgcrypto"/> module also provides a generation
4205-
function for random UUIDs.
4206-
Alternatively, UUIDs could be generated by client applications or
4207-
other libraries invoked through a server-side function.
4198+
See <xref linkend="functions-uuid"/> for how to generate a UUID in
4199+
<productname>PostgreSQL</productname>.
42084200
</para>
42094201
</sect1>
42104202

doc/src/sgml/func.sgml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10267,6 +10267,32 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
1026710267

1026810268
</sect1>
1026910269

10270+
<sect1 id="functions-uuid">
10271+
<title>UUID Functions</title>
10272+
10273+
<indexterm zone="datatype-uuid">
10274+
<primary>UUID</primary>
10275+
<secondary>generating</secondary>
10276+
</indexterm>
10277+
10278+
<indexterm>
10279+
<primary>gen_random_uuid</primary>
10280+
</indexterm>
10281+
10282+
<para>
10283+
<productname>PostgreSQL</productname> includes one function to generate a UUID:
10284+
<synopsis>
10285+
gen_random_uuid() returns uuid
10286+
</synopsis>
10287+
This function returns a version 4 (random) UUID. This is the most commonly
10288+
used type of UUID and is appropriate for most applications.
10289+
</para>
10290+
10291+
<para>
10292+
The <xref linkend="uuid-ossp"/> module provides additional functions that
10293+
implement other standard algorithms for generating UUIDs.
10294+
</para>
10295+
</sect1>
1027010296

1027110297
<sect1 id="functions-xml">
1027210298

doc/src/sgml/pgcrypto.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,8 @@ gen_random_bytes(count integer) returns bytea
11321132
gen_random_uuid() returns uuid
11331133
</synopsis>
11341134
<para>
1135-
Returns a version 4 (random) UUID.
1135+
Returns a version 4 (random) UUID. (Obsolete, this function is now also
1136+
included in core <productname>PostgreSQL</productname>.)
11361137
</para>
11371138
</sect2>
11381139

doc/src/sgml/uuid-ossp.sgml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
The <filename>uuid-ossp</filename> module provides functions to generate universally
1212
unique identifiers (UUIDs) using one of several standard algorithms. There
1313
are also functions to produce certain special UUID constants.
14+
This module is only necessary for special requirements beyond what is
15+
available in core <productname>PostgreSQL</productname>. See <xref
16+
linkend="functions-uuid"/> for built-in ways to generate UUIDs.
1417
</para>
1518

1619
<sect2>
@@ -181,14 +184,6 @@ SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org');
181184
More than one of these libraries might be available on a particular
182185
machine, so <filename>configure</filename> does not automatically choose one.
183186
</para>
184-
185-
<note>
186-
<para>
187-
If you only need randomly-generated (version 4) UUIDs,
188-
consider using the <function>gen_random_uuid()</function> function
189-
from the <xref linkend="pgcrypto"/> module instead.
190-
</para>
191-
</note>
192187
</sect2>
193188

194189
<sect2>

src/backend/utils/adt/uuid.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,23 @@ uuid_hash_extended(PG_FUNCTION_ARGS)
416416

417417
return hash_any_extended(key->data, UUID_LEN, PG_GETARG_INT64(1));
418418
}
419+
420+
Datum
421+
gen_random_uuid(PG_FUNCTION_ARGS)
422+
{
423+
pg_uuid_t *uuid = palloc(UUID_LEN);
424+
425+
if (!pg_strong_random(uuid, UUID_LEN))
426+
ereport(ERROR,
427+
(errcode(ERRCODE_INTERNAL_ERROR),
428+
errmsg("could not generate random values")));
429+
430+
/*
431+
* Set magic numbers for a "version 4" (pseudorandom) UUID, see
432+
* http://tools.ietf.org/html/rfc4122#section-4.4
433+
*/
434+
uuid->data[6] = (uuid->data[6] & 0x0f) | 0x40; /* time_hi_and_version */
435+
uuid->data[8] = (uuid->data[8] & 0x3f) | 0x80; /* clock_seq_hi_and_reserved */
436+
437+
PG_RETURN_UUID_P(uuid);
438+
}

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201907141
56+
#define CATALOG_VERSION_NO 201907142
5757

5858
#endif

src/include/catalog/pg_proc.dat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8376,6 +8376,9 @@
83768376
{ oid => '3412', descr => 'hash',
83778377
proname => 'uuid_hash_extended', prorettype => 'int8',
83788378
proargtypes => 'uuid int8', prosrc => 'uuid_hash_extended' },
8379+
{ oid => '3432', descr => 'generate random UUID',
8380+
proname => 'gen_random_uuid', proleakproof => 't', prorettype => 'uuid',
8381+
proargtypes => '', prosrc => 'gen_random_uuid' },
83798382

83808383
# pg_lsn
83818384
{ oid => '3229', descr => 'I/O',

src/test/regress/expected/opr_sanity.out

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ sha224(bytea)
742742
sha256(bytea)
743743
sha384(bytea)
744744
sha512(bytea)
745+
gen_random_uuid()
745746
starts_with(text,text)
746747
macaddr8_eq(macaddr8,macaddr8)
747748
macaddr8_lt(macaddr8,macaddr8)

src/test/regress/expected/uuid.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,15 @@ SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_fiel
145145
1
146146
(1 row)
147147

148+
-- generation test
149+
TRUNCATE guid1;
150+
INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid());
151+
INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid());
152+
SELECT count(DISTINCT guid_field) FROM guid1;
153+
count
154+
-------
155+
2
156+
(1 row)
157+
148158
-- clean up
149159
DROP TABLE guid1, guid2 CASCADE;

src/test/regress/sql/uuid.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,11 @@ INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e');
7575
SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field;
7676
SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL;
7777

78+
-- generation test
79+
TRUNCATE guid1;
80+
INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid());
81+
INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid());
82+
SELECT count(DISTINCT guid_field) FROM guid1;
83+
7884
-- clean up
7985
DROP TABLE guid1, guid2 CASCADE;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy