]> granicus.if.org Git - postgresql/commitdiff
Add gen_random_uuid() to contrib/pgcrypto.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 17 Jan 2014 21:52:06 +0000 (16:52 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 17 Jan 2014 21:52:06 +0000 (16:52 -0500)
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

contrib/pgcrypto/Makefile
contrib/pgcrypto/pgcrypto--1.0--1.1.sql [new file with mode: 0644]
contrib/pgcrypto/pgcrypto--1.1.sql [moved from contrib/pgcrypto/pgcrypto--1.0.sql with 96% similarity]
contrib/pgcrypto/pgcrypto.c
contrib/pgcrypto/pgcrypto.control
contrib/pgcrypto/pgcrypto.h
doc/src/sgml/datatype.sgml
doc/src/sgml/pgcrypto.sgml
doc/src/sgml/uuid-ossp.sgml

index dadec953c2aa03006de621405ddd3d27b9d5e04a..1c85c982ff94374a8a33571ca94a58574765d227 100644 (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) \
diff --git a/contrib/pgcrypto/pgcrypto--1.0--1.1.sql b/contrib/pgcrypto/pgcrypto--1.0--1.1.sql
new file mode 100644 (file)
index 0000000..42e0c7f
--- /dev/null
@@ -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;
similarity index 96%
rename from contrib/pgcrypto/pgcrypto--1.0.sql
rename to contrib/pgcrypto/pgcrypto--1.1.sql
index 347825ea07d363df30e9c4e2df4b1620fc36f3ee..a260857d3029bb0c04b48e3334c7b47d8b6c5794 100644 (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)
 --
index a441ca77f124e361828ca7872b360d2a3b35a275..9917e18d864ee462682130734ae4ed82febdb54b 100644 (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,
index 8375cf9e7bb71da981dbe12b359238169b5e23a1..7f79d044ab30e7c014a06b258ca4532f05f22766 100644 (file)
@@ -1,5 +1,5 @@
 # pgcrypto extension
 comment = 'cryptographic functions'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/pgcrypto'
 relocatable = true
index 6284ba2406adcf5ef732d4b81af776a2634a6ead..04ea696ac38d44e1c24b9f6411c3530c4416cd43 100644 (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
index 03863300d4a6f94d046c5b86b1941ce6d8475ea6..6bf4cf61d8659d48df9cd3cd41a42792f88f0810 100644 (file)
@@ -4015,6 +4015,8 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
     suited for every application.  The <xref
     linkend="uuid-ossp"> module
     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
     other libraries invoked through a server-side function.
    </para>
index b99a75c36688b4ef3f23b3c753356735f862a95e..31dba8cb73154c9d4f1aaa2e8cb286fee8be9896 100644 (file)
@@ -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
    draining the randomness generator pool.
   </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>
index 696cc112dc89fcd69c49b962492dc5d8f8d4eb1f..c48106ba0f4ab8503637b2379157d0a4644e0e07 100644 (file)
   <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
  </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>
   <title><literal>uuid-ossp</literal> Functions</title>