Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e617012

Browse files
committed
Add gen_random_uuid() to contrib/pgcrypto.
This function provides a way of generating version 4 (pseudorandom) UUIDs based on pgcrypto's PRNG. The main reason for doing this is that the OSSP UUID library depended on by contrib/uuid-ossp is becoming more and more of a porting headache, so we need an alternative for people who can't install that. A nice side benefit though is that this implementation is noticeably faster than uuid-ossp's uuid_generate_v4() function. Oskari Saarenmaa, reviewed by Emre Hasegeli
1 parent 708c529 commit e617012

File tree

9 files changed

+67
-3
lines changed

9 files changed

+67
-3
lines changed

contrib/pgcrypto/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ MODULE_big = pgcrypto
2626
OBJS = $(SRCS:.c=.o)
2727

2828
EXTENSION = pgcrypto
29-
DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
29+
DATA = pgcrypto--1.1.sql pgcrypto--1.0--1.1.sql pgcrypto--unpackaged--1.0.sql
3030

3131
REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
3232
$(CF_TESTS) \
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* contrib/pgcrypto/pgcrypto--1.0--1.1.sql */
2+
3+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
4+
\echo Use "ALTER EXTENSION pgcrypto UPDATE TO '1.1'" to load this file. \quit
5+
6+
CREATE FUNCTION gen_random_uuid()
7+
RETURNS uuid
8+
AS 'MODULE_PATHNAME', 'pg_random_uuid'
9+
LANGUAGE C VOLATILE;

contrib/pgcrypto/pgcrypto--1.0.sql renamed to contrib/pgcrypto/pgcrypto--1.1.sql

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* contrib/pgcrypto/pgcrypto--1.0.sql */
1+
/* contrib/pgcrypto/pgcrypto--1.1.sql */
22

33
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
44
\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
@@ -63,6 +63,11 @@ RETURNS bytea
6363
AS 'MODULE_PATHNAME', 'pg_random_bytes'
6464
LANGUAGE C VOLATILE STRICT;
6565

66+
CREATE FUNCTION gen_random_uuid()
67+
RETURNS uuid
68+
AS 'MODULE_PATHNAME', 'pg_random_uuid'
69+
LANGUAGE C VOLATILE;
70+
6671
--
6772
-- pgp_sym_encrypt(data, key)
6873
--

contrib/pgcrypto/pgcrypto.c

+27
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
#include "parser/scansup.h"
3737
#include "utils/builtins.h"
38+
#include "utils/uuid.h"
3839

3940
#include "px.h"
4041
#include "px-crypt.h"
@@ -443,6 +444,32 @@ pg_random_bytes(PG_FUNCTION_ARGS)
443444
PG_RETURN_BYTEA_P(res);
444445
}
445446

447+
/* SQL function: gen_random_uuid() returns uuid */
448+
PG_FUNCTION_INFO_V1(pg_random_uuid);
449+
450+
Datum
451+
pg_random_uuid(PG_FUNCTION_ARGS)
452+
{
453+
uint8 *buf = (uint8 *) palloc(UUID_LEN);
454+
int err;
455+
456+
/* generate random bits */
457+
err = px_get_pseudo_random_bytes(buf, UUID_LEN);
458+
if (err < 0)
459+
ereport(ERROR,
460+
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
461+
errmsg("Random generator error: %s", px_strerror(err))));
462+
463+
/*
464+
* Set magic numbers for a "version 4" (pseudorandom) UUID, see
465+
* http://tools.ietf.org/html/rfc4122#section-4.4
466+
*/
467+
buf[6] = (buf[6] & 0x0f) | 0x40; /* "version" field */
468+
buf[8] = (buf[8] & 0x3f) | 0x80; /* "variant" field */
469+
470+
PG_RETURN_UUID_P((pg_uuid_t *) buf);
471+
}
472+
446473
static void *
447474
find_provider(text *name,
448475
PFN provider_lookup,

contrib/pgcrypto/pgcrypto.control

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# pgcrypto extension
22
comment = 'cryptographic functions'
3-
default_version = '1.0'
3+
default_version = '1.1'
44
module_pathname = '$libdir/pgcrypto'
55
relocatable = true

contrib/pgcrypto/pgcrypto.h

+1
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,6 @@ Datum pg_decrypt(PG_FUNCTION_ARGS);
4545
Datum pg_encrypt_iv(PG_FUNCTION_ARGS);
4646
Datum pg_decrypt_iv(PG_FUNCTION_ARGS);
4747
Datum pg_random_bytes(PG_FUNCTION_ARGS);
48+
Datum pg_random_uuid(PG_FUNCTION_ARGS);
4849

4950
#endif

doc/src/sgml/datatype.sgml

+2
Original file line numberDiff line numberDiff line change
@@ -4015,6 +4015,8 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
40154015
suited for every application. The <xref
40164016
linkend="uuid-ossp"> module
40174017
provides functions that implement several standard algorithms.
4018+
The <xref linkend="pgcrypto"> module also provides a generation
4019+
function for random UUIDs.
40184020
Alternatively, UUIDs could be generated by client applications or
40194021
other libraries invoked through a server-side function.
40204022
</para>

doc/src/sgml/pgcrypto.sgml

+11
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,17 @@ gen_random_bytes(count integer) returns bytea
10841084
At most 1024 bytes can be extracted at a time. This is to avoid
10851085
draining the randomness generator pool.
10861086
</para>
1087+
1088+
<indexterm>
1089+
<primary>gen_random_uuid</primary>
1090+
</indexterm>
1091+
1092+
<synopsis>
1093+
gen_random_uuid() returns uuid
1094+
</synopsis>
1095+
<para>
1096+
Returns a version 4 (random) UUID.
1097+
</para>
10871098
</sect2>
10881099

10891100
<sect2>

doc/src/sgml/uuid-ossp.sgml

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818
<ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
1919
</para>
2020

21+
<note>
22+
<para>
23+
The OSSP UUID library is not well maintained, and is becoming increasingly
24+
difficult to port to newer platforms. If you only need randomly-generated
25+
(version 4) UUIDs, consider using the <function>gen_random_uuid()</>
26+
function from the <xref linkend="pgcrypto"> module instead.
27+
</para>
28+
</note>
29+
2130
<sect2>
2231
<title><literal>uuid-ossp</literal> Functions</title>
2332

0 commit comments

Comments
 (0)