提交 e6170126 编写于 作者: T Tom Lane

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
上级 708c529c
...@@ -26,7 +26,7 @@ MODULE_big = pgcrypto ...@@ -26,7 +26,7 @@ MODULE_big = pgcrypto
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)
EXTENSION = pgcrypto 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 \ REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
$(CF_TESTS) \ $(CF_TESTS) \
......
/* 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;
/* contrib/pgcrypto/pgcrypto--1.0.sql */ /* contrib/pgcrypto/pgcrypto--1.1.sql */
-- complain if script is sourced in psql, rather than via CREATE EXTENSION -- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit \echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
...@@ -63,6 +63,11 @@ RETURNS bytea ...@@ -63,6 +63,11 @@ RETURNS bytea
AS 'MODULE_PATHNAME', 'pg_random_bytes' AS 'MODULE_PATHNAME', 'pg_random_bytes'
LANGUAGE C VOLATILE STRICT; 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) -- pgp_sym_encrypt(data, key)
-- --
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "parser/scansup.h" #include "parser/scansup.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/uuid.h"
#include "px.h" #include "px.h"
#include "px-crypt.h" #include "px-crypt.h"
...@@ -443,6 +444,32 @@ pg_random_bytes(PG_FUNCTION_ARGS) ...@@ -443,6 +444,32 @@ pg_random_bytes(PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P(res); 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 * static void *
find_provider(text *name, find_provider(text *name,
PFN provider_lookup, PFN provider_lookup,
......
# pgcrypto extension # pgcrypto extension
comment = 'cryptographic functions' comment = 'cryptographic functions'
default_version = '1.0' default_version = '1.1'
module_pathname = '$libdir/pgcrypto' module_pathname = '$libdir/pgcrypto'
relocatable = true relocatable = true
...@@ -45,5 +45,6 @@ Datum pg_decrypt(PG_FUNCTION_ARGS); ...@@ -45,5 +45,6 @@ Datum pg_decrypt(PG_FUNCTION_ARGS);
Datum pg_encrypt_iv(PG_FUNCTION_ARGS); Datum pg_encrypt_iv(PG_FUNCTION_ARGS);
Datum pg_decrypt_iv(PG_FUNCTION_ARGS); Datum pg_decrypt_iv(PG_FUNCTION_ARGS);
Datum pg_random_bytes(PG_FUNCTION_ARGS); Datum pg_random_bytes(PG_FUNCTION_ARGS);
Datum pg_random_uuid(PG_FUNCTION_ARGS);
#endif #endif
...@@ -4015,6 +4015,8 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 ...@@ -4015,6 +4015,8 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
suited for every application. The <xref suited for every application. The <xref
linkend="uuid-ossp"> module linkend="uuid-ossp"> module
provides functions that implement several standard algorithms. provides functions that implement several standard algorithms.
The <xref linkend="pgcrypto"> module also provides a generation
function for random UUIDs.
Alternatively, UUIDs could be generated by client applications or Alternatively, UUIDs could be generated by client applications or
other libraries invoked through a server-side function. other libraries invoked through a server-side function.
</para> </para>
......
...@@ -1084,6 +1084,17 @@ gen_random_bytes(count integer) returns bytea ...@@ -1084,6 +1084,17 @@ gen_random_bytes(count integer) returns bytea
At most 1024 bytes can be extracted at a time. This is to avoid At most 1024 bytes can be extracted at a time. This is to avoid
draining the randomness generator pool. draining the randomness generator pool.
</para> </para>
<indexterm>
<primary>gen_random_uuid</primary>
</indexterm>
<synopsis>
gen_random_uuid() returns uuid
</synopsis>
<para>
Returns a version 4 (random) UUID.
</para>
</sect2> </sect2>
<sect2> <sect2>
......
...@@ -18,6 +18,15 @@ ...@@ -18,6 +18,15 @@
<ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>. <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
</para> </para>
<note>
<para>
The OSSP UUID library is not well maintained, and is becoming increasingly
difficult to port to newer platforms. If you only need randomly-generated
(version 4) UUIDs, consider using the <function>gen_random_uuid()</>
function from the <xref linkend="pgcrypto"> module instead.
</para>
</note>
<sect2> <sect2>
<title><literal>uuid-ossp</literal> Functions</title> <title><literal>uuid-ossp</literal> Functions</title>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册