1
0
mirror of https://github.com/postgres/postgres.git synced 2026-01-05 23:38:41 +03:00

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
This commit is contained in:
Tom Lane
2014-01-17 16:52:06 -05:00
parent 708c529c7f
commit e6170126fc
9 changed files with 67 additions and 3 deletions

View File

@@ -26,7 +26,7 @@ MODULE_big = pgcrypto
OBJS = $(SRCS:.c=.o)
EXTENSION = pgcrypto
DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
DATA = pgcrypto--1.1.sql pgcrypto--1.0--1.1.sql pgcrypto--unpackaged--1.0.sql
REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
$(CF_TESTS) \

View File

@@ -0,0 +1,9 @@
/* contrib/pgcrypto/pgcrypto--1.0--1.1.sql */
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
\echo Use "ALTER EXTENSION pgcrypto UPDATE TO '1.1'" to load this file. \quit
CREATE FUNCTION gen_random_uuid()
RETURNS uuid
AS 'MODULE_PATHNAME', 'pg_random_uuid'
LANGUAGE C VOLATILE;

View File

@@ -1,4 +1,4 @@
/* contrib/pgcrypto/pgcrypto--1.0.sql */
/* contrib/pgcrypto/pgcrypto--1.1.sql */
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
@@ -63,6 +63,11 @@ RETURNS bytea
AS 'MODULE_PATHNAME', 'pg_random_bytes'
LANGUAGE C VOLATILE STRICT;
CREATE FUNCTION gen_random_uuid()
RETURNS uuid
AS 'MODULE_PATHNAME', 'pg_random_uuid'
LANGUAGE C VOLATILE;
--
-- pgp_sym_encrypt(data, key)
--

View File

@@ -35,6 +35,7 @@
#include "parser/scansup.h"
#include "utils/builtins.h"
#include "utils/uuid.h"
#include "px.h"
#include "px-crypt.h"
@@ -443,6 +444,32 @@ pg_random_bytes(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(res);
}
/* SQL function: gen_random_uuid() returns uuid */
PG_FUNCTION_INFO_V1(pg_random_uuid);
Datum
pg_random_uuid(PG_FUNCTION_ARGS)
{
uint8 *buf = (uint8 *) palloc(UUID_LEN);
int err;
/* generate random bits */
err = px_get_pseudo_random_bytes(buf, UUID_LEN);
if (err < 0)
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
errmsg("Random generator error: %s", px_strerror(err))));
/*
* Set magic numbers for a "version 4" (pseudorandom) UUID, see
* http://tools.ietf.org/html/rfc4122#section-4.4
*/
buf[6] = (buf[6] & 0x0f) | 0x40; /* "version" field */
buf[8] = (buf[8] & 0x3f) | 0x80; /* "variant" field */
PG_RETURN_UUID_P((pg_uuid_t *) buf);
}
static void *
find_provider(text *name,
PFN provider_lookup,

View File

@@ -1,5 +1,5 @@
# pgcrypto extension
comment = 'cryptographic functions'
default_version = '1.0'
default_version = '1.1'
module_pathname = '$libdir/pgcrypto'
relocatable = true

View File

@@ -45,5 +45,6 @@ Datum pg_decrypt(PG_FUNCTION_ARGS);
Datum pg_encrypt_iv(PG_FUNCTION_ARGS);
Datum pg_decrypt_iv(PG_FUNCTION_ARGS);
Datum pg_random_bytes(PG_FUNCTION_ARGS);
Datum pg_random_uuid(PG_FUNCTION_ARGS);
#endif