summaryrefslogtreecommitdiff
path: root/shared/ossp_uuid/pgsql
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:02:17 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:02:17 +0200
commitb9203ee84953006547f4afd58f405874c87bf0dc (patch)
tree9e41f1533f120e9268e86658c52458630ffd718a /shared/ossp_uuid/pgsql
parent3.0 (diff)
downloadFreeFileSync-b9203ee84953006547f4afd58f405874c87bf0dc.tar.gz
FreeFileSync-b9203ee84953006547f4afd58f405874c87bf0dc.tar.bz2
FreeFileSync-b9203ee84953006547f4afd58f405874c87bf0dc.zip
3.1
Diffstat (limited to 'shared/ossp_uuid/pgsql')
-rw-r--r--shared/ossp_uuid/pgsql/Makefile57
-rw-r--r--shared/ossp_uuid/pgsql/uuid.c436
-rw-r--r--shared/ossp_uuid/pgsql/uuid.sql.in244
-rw-r--r--shared/ossp_uuid/pgsql/uuid.txt36
4 files changed, 773 insertions, 0 deletions
diff --git a/shared/ossp_uuid/pgsql/Makefile b/shared/ossp_uuid/pgsql/Makefile
new file mode 100644
index 00000000..a71bbc21
--- /dev/null
+++ b/shared/ossp_uuid/pgsql/Makefile
@@ -0,0 +1,57 @@
+##
+## Makefile for PostgreSQL extension module
+##
+
+# NOTICE: This requires GNU make as the PostgreSQL PGXS build
+# environment is based on GNU make features!
+#
+# NOTICE: Usually one would just use "PGXS := $(shell pg_config
+# --pgxs)" followed by "include $(PGXS)" as the template. The problem
+# just is that this way (at least still under PostgreSQL 8.1) one
+# cannot pass the "-L../.libs -luuid" to the command which links the
+# DSO. Hence we fiddle around with the Makefiles which "PGXS" uses
+# itself ourself.
+
+PG_CONFIG ?= pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+POSTGRES := $(shell $(PG_CONFIG) --bindir)/postgres
+top_builddir := $(dir $(PGXS))../..
+include $(top_builddir)/src/Makefile.global
+
+NAME = uuid
+OBJS = uuid.o
+SO_MAJOR_VERSION = 1
+SO_MINOR_VERSION = 0
+
+override CPPFLAGS := -I.. $(CPPFLAGS)
+SHLIB_LINK := -L../.libs -luuid
+SHLIB_LINK += $(shell test $(shell uname -s) = FreeBSD && echo "-Wl,-Bsymbolic")
+SHLIB_LINK += $(shell test $(shell uname -s) = Darwin && echo "-bundle_loader $(POSTGRES)")
+rpath :=
+
+all: uuid.sql all-lib
+
+enable_shared = yes
+include $(top_builddir)/src/Makefile.shlib
+
+uuid.sql: uuid.sql.in
+ sed -e 's;MODULE_PATHNAME;$(DESTDIR)$(pkglibdir)/uuid$(DLSUFFIX);g' <uuid.sql.in >uuid.sql
+
+install: all
+ $(mkinstalldirs) $(DESTDIR)$(pkglibdir)
+ $(mkinstalldirs) $(DESTDIR)$(datadir)
+ $(INSTALL_SHLIB) $(shlib) $(DESTDIR)$(pkglibdir)/uuid$(DLSUFFIX)
+ $(INSTALL_DATA) uuid.sql $(DESTDIR)$(datadir)/uuid.sql
+
+uninstall:
+ -rm -f $(DESTDIR)$(pkglibdir)/uuid$(DLSUFFIX)
+ -rm -f $(DESTDIR)$(datadir)/uuid.sql
+
+clean distclean: clean-lib
+ rm -f $(OBJS)
+ rm -f uuid.sql
+
+realclean: distclean
+
+test:
+
diff --git a/shared/ossp_uuid/pgsql/uuid.c b/shared/ossp_uuid/pgsql/uuid.c
new file mode 100644
index 00000000..023eda96
--- /dev/null
+++ b/shared/ossp_uuid/pgsql/uuid.c
@@ -0,0 +1,436 @@
+/*
+** OSSP uuid - Universally Unique Identifier
+** Copyright (c) 2004-2007 Ralf S. Engelschall <rse@engelschall.com>
+** Copyright (c) 2004-2007 The OSSP Project <http://www.ossp.org/>
+**
+** This file is part of OSSP uuid, a library for the generation
+** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+**
+** Permission to use, copy, modify, and distribute this software for
+** any purpose with or without fee is hereby granted, provided that
+** the above copyright notice and this permission notice appear in all
+** copies.
+**
+** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+** SUCH DAMAGE.
+**
+** uuid.c: PostgreSQL Binding (C part)
+*/
+
+/* own headers */
+#include "uuid.h"
+
+/* PostgreSQL (part 1/2) headers */
+#include "postgres.h"
+
+/* system headers */
+#include <string.h>
+
+/* PostgreSQL (part 2/2) headers */
+#include "fmgr.h"
+#include "lib/stringinfo.h"
+#include "access/hash.h"
+
+/* PostgreSQL module magic cookie
+ (PostgreSQL >= 8.2 only) */
+#ifdef PG_MODULE_MAGIC
+PG_MODULE_MAGIC;
+#endif
+
+/* internal UUID datum data structure */
+typedef struct {
+ unsigned char uuid_bin[UUID_LEN_BIN];
+} uuid_datum_t;
+
+/* forward declarations */
+Datum pg_uuid_in (PG_FUNCTION_ARGS);
+Datum pg_uuid_out (PG_FUNCTION_ARGS);
+Datum pg_uuid_recv (PG_FUNCTION_ARGS);
+Datum pg_uuid_send (PG_FUNCTION_ARGS);
+Datum pg_uuid_hash (PG_FUNCTION_ARGS);
+Datum pg_uuid_make (PG_FUNCTION_ARGS);
+Datum pg_uuid_eq (PG_FUNCTION_ARGS);
+Datum pg_uuid_ne (PG_FUNCTION_ARGS);
+Datum pg_uuid_lt (PG_FUNCTION_ARGS);
+Datum pg_uuid_gt (PG_FUNCTION_ARGS);
+Datum pg_uuid_le (PG_FUNCTION_ARGS);
+Datum pg_uuid_ge (PG_FUNCTION_ARGS);
+Datum pg_uuid_cmp (PG_FUNCTION_ARGS);
+
+/* API function: uuid_in */
+PG_FUNCTION_INFO_V1(pg_uuid_in);
+Datum pg_uuid_in(PG_FUNCTION_ARGS)
+{
+ char *uuid_str;
+ uuid_datum_t *uuid_datum;
+ uuid_rc_t rc;
+ uuid_t *uuid;
+ void *vp;
+ size_t len;
+
+ /* sanity check input argument */
+ if ((uuid_str = PG_GETARG_CSTRING(0)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID string")));
+ if ((len = strlen(uuid_str)) != UUID_LEN_STR)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID string length %d (expected %d)", (int)len, UUID_LEN_STR)));
+
+ /* import as string representation */
+ if ((rc = uuid_create(&uuid)) != UUID_RC_OK)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to create UUID object: %s", uuid_error(rc))));
+ if ((rc = uuid_import(uuid, UUID_FMT_STR, uuid_str, len)) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to import UUID string representation: %s", uuid_error(rc))));
+ }
+
+ /* export as binary representation */
+ if ((uuid_datum = (uuid_datum_t *)palloc(sizeof(uuid_datum_t))) == NULL) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to allocate UUID datum")));
+ }
+ vp = &(uuid_datum->uuid_bin);
+ len = sizeof(uuid_datum->uuid_bin);
+ if ((rc = uuid_export(uuid, UUID_FMT_BIN, &vp, &len)) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to export UUID binary representation: %s", uuid_error(rc))));
+ }
+ uuid_destroy(uuid);
+
+ /* return UUID datum */
+ PG_RETURN_POINTER(uuid_datum);
+}
+
+/* API function: uuid_out */
+PG_FUNCTION_INFO_V1(pg_uuid_out);
+Datum pg_uuid_out(PG_FUNCTION_ARGS)
+{
+ uuid_datum_t *uuid_datum;
+ uuid_rc_t rc;
+ uuid_t *uuid;
+ char *uuid_str;
+ void *vp;
+ size_t len;
+
+ /* sanity check input argument */
+ if ((uuid_datum = (uuid_datum_t *)PG_GETARG_POINTER(0)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID datum")));
+
+ /* import as binary representation */
+ if ((rc = uuid_create(&uuid)) != UUID_RC_OK)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to create UUID object: %s", uuid_error(rc))));
+ if ((rc = uuid_import(uuid, UUID_FMT_BIN, uuid_datum->uuid_bin, sizeof(uuid_datum->uuid_bin))) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to import UUID binary representation: %s", uuid_error(rc))));
+ }
+
+ /* export as string representation */
+ len = UUID_LEN_STR+1;
+ if ((vp = uuid_str = (char *)palloc(len)) == NULL) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to allocate UUID string")));
+ }
+ if ((rc = uuid_export(uuid, UUID_FMT_STR, &vp, &len)) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to export UUID string representation: %s", uuid_error(rc))));
+ }
+ uuid_destroy(uuid);
+
+ /* return UUID string */
+ PG_RETURN_CSTRING(uuid_str);
+}
+
+/* API function: uuid_recv */
+PG_FUNCTION_INFO_V1(pg_uuid_recv);
+Datum pg_uuid_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo uuid_internal;
+ uuid_datum_t *uuid_datum;
+
+ /* sanity check input argument */
+ if ((uuid_internal = (StringInfo)PG_GETARG_POINTER(0)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID StringInfo object")));
+ if (uuid_internal->len != UUID_LEN_BIN)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID binary length %d (expected %d)", uuid_internal->len, UUID_LEN_BIN)));
+
+ /* import as binary representation */
+ if ((uuid_datum = (uuid_datum_t *)palloc(sizeof(uuid_datum_t))) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to allocate UUID datum")));
+ memcpy(uuid_datum->uuid_bin, uuid_internal->data, uuid_internal->len);
+
+ /* return UUID datum */
+ PG_RETURN_POINTER(uuid_datum);
+}
+
+/* API function: uuid_send */
+PG_FUNCTION_INFO_V1(pg_uuid_send);
+Datum pg_uuid_send(PG_FUNCTION_ARGS)
+{
+ uuid_datum_t *uuid_datum;
+ bytea *uuid_bytea;
+
+ /* sanity check input argument */
+ if ((uuid_datum = (uuid_datum_t *)PG_GETARG_POINTER(0)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID datum")));
+
+ /* export as binary representation */
+ if ((uuid_bytea = (bytea *)palloc(VARHDRSZ + UUID_LEN_BIN)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to allocate UUID bytea")));
+#if defined(SET_VARSIZE) /* PostgreSQL >= 8.3 */
+ SET_VARSIZE(uuid_bytea, VARHDRSZ + UUID_LEN_BIN);
+#else
+ uuid_bytea->vl_len = VARHDRSZ + UUID_LEN_BIN;
+#endif
+ memcpy(uuid_bytea->vl_dat, uuid_datum->uuid_bin, UUID_LEN_BIN);
+
+ /* return UUID bytea */
+ PG_RETURN_BYTEA_P(uuid_bytea);
+}
+
+/* API function: uuid_make */
+PG_FUNCTION_INFO_V1(pg_uuid_make);
+Datum pg_uuid_make(PG_FUNCTION_ARGS)
+{
+ uuid_t *uuid;
+ uuid_t *uuid_ns;
+ uuid_rc_t rc;
+ int version;
+ unsigned int mode = 0;
+ uuid_datum_t *uuid_datum;
+ char *str_ns;
+ char *str_name;
+ void *vp;
+ size_t len;
+
+ /* sanity check input argument */
+ version = (int)PG_GETARG_INT32(0);
+ switch (version) {
+ case 1: mode = UUID_MAKE_V1; break;
+ case 3: mode = UUID_MAKE_V3; break;
+ case 4: mode = UUID_MAKE_V4; break;
+ case 5: mode = UUID_MAKE_V5; break;
+ default:
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID version %d (expected 1, 3, 4 or 5)", version)));
+ }
+ if ( ((mode & (UUID_MAKE_V1|UUID_MAKE_V4)) && PG_NARGS() != 1)
+ || ((mode & (UUID_MAKE_V3|UUID_MAKE_V5)) && PG_NARGS() != 3))
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid number (%d) of arguments", PG_NARGS())));
+
+ /* make a new UUID */
+ if ((rc = uuid_create(&uuid)) != UUID_RC_OK)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to create UUID object: %s", uuid_error(rc))));
+ if (version == 3 || version == 5) {
+ if ((str_ns = PG_GETARG_CSTRING(1)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid namespace UUID string")));
+ if ((str_name = PG_GETARG_CSTRING(2)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid name string")));
+ if ((rc = uuid_create(&uuid_ns)) != UUID_RC_OK)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to create UUID namespace object: %s", uuid_error(rc))));
+ if ((rc = uuid_load(uuid_ns, str_ns)) != UUID_RC_OK) {
+ if ((rc = uuid_import(uuid_ns, UUID_FMT_STR, str_ns, strlen(str_ns))) != UUID_RC_OK)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to import UUID namespace: %s", uuid_error(rc))));
+ }
+ if ((rc = uuid_make(uuid, mode, uuid_ns, str_name)) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to make v%d UUID: %s", version, uuid_error(rc))));
+ }
+ uuid_destroy(uuid_ns);
+ }
+ else {
+ if ((rc = uuid_make(uuid, mode)) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to make v%d UUID: %s", version, uuid_error(rc))));
+ }
+ }
+
+ /* export as binary representation */
+ if ((uuid_datum = (uuid_datum_t *)palloc(sizeof(uuid_datum_t))) == NULL) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to allocate UUID datum")));
+ }
+ vp = &(uuid_datum->uuid_bin);
+ len = sizeof(uuid_datum->uuid_bin);
+ if ((rc = uuid_export(uuid, UUID_FMT_BIN, &vp, &len)) != UUID_RC_OK) {
+ uuid_destroy(uuid);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to export UUID binary representation: %s", uuid_error(rc))));
+ }
+ uuid_destroy(uuid);
+ PG_RETURN_POINTER(uuid_datum);
+}
+
+/* API function: uuid_hash */
+PG_FUNCTION_INFO_V1(pg_uuid_hash);
+Datum pg_uuid_hash(PG_FUNCTION_ARGS)
+{
+ uuid_datum_t *uuid_datum;
+
+ /* sanity check input argument */
+ if ((uuid_datum = (uuid_datum_t *)PG_GETARG_POINTER(0)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid UUID datum argument")));
+
+ /* return hash value of the UUID */
+ PG_RETURN_INT32(hash_any(uuid_datum->uuid_bin, sizeof(uuid_datum->uuid_bin)));
+}
+
+/* INTERNAL function: _uuid_cmp */
+static int _uuid_cmp(PG_FUNCTION_ARGS)
+{
+ uuid_datum_t *uuid_datum1;
+ uuid_datum_t *uuid_datum2;
+ uuid_t *uuid1;
+ uuid_t *uuid2;
+ uuid_rc_t rc;
+ int result;
+
+ /* sanity check input argument */
+ if ((uuid_datum1 = (uuid_datum_t *)PG_GETARG_POINTER(0)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid first UUID datum argument")));
+ if ((uuid_datum2 = (uuid_datum_t *)PG_GETARG_POINTER(1)) == NULL)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("invalid second UUID datum argument")));
+
+ /* load both UUIDs */
+ if ((rc = uuid_create(&uuid1)) != UUID_RC_OK)
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to create UUID object: %s", uuid_error(rc))));
+ if ((rc = uuid_create(&uuid2)) != UUID_RC_OK) {
+ uuid_destroy(uuid1);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to create UUID object: %s", uuid_error(rc))));
+ }
+ if ((rc = uuid_import(uuid1, UUID_FMT_BIN, uuid_datum1->uuid_bin, sizeof(uuid_datum1->uuid_bin))) != UUID_RC_OK) {
+ uuid_destroy(uuid1);
+ uuid_destroy(uuid2);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to import UUID: %s", uuid_error(rc))));
+ }
+ if ((rc = uuid_import(uuid2, UUID_FMT_BIN, uuid_datum2->uuid_bin, sizeof(uuid_datum2->uuid_bin))) != UUID_RC_OK) {
+ uuid_destroy(uuid1);
+ uuid_destroy(uuid2);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to import UUID: %s", uuid_error(rc))));
+ }
+
+ /* compare UUIDs */
+ if ((rc = uuid_compare(uuid1, uuid2, &result)) != UUID_RC_OK) {
+ uuid_destroy(uuid1);
+ uuid_destroy(uuid2);
+ ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION),
+ errmsg("failed to compare UUID objects: %s", uuid_error(rc))));
+ }
+
+ /* cleanup */
+ uuid_destroy(uuid1);
+ uuid_destroy(uuid2);
+
+ /* return result */
+ return result;
+}
+
+/* API function: uuid_eq */
+PG_FUNCTION_INFO_V1(pg_uuid_eq);
+Datum pg_uuid_eq(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_BOOL(rc == 0);
+}
+
+/* API function: uuid_ne */
+PG_FUNCTION_INFO_V1(pg_uuid_ne);
+Datum pg_uuid_ne(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_BOOL(rc != 0);
+}
+
+/* API function: uuid_lt */
+PG_FUNCTION_INFO_V1(pg_uuid_lt);
+Datum pg_uuid_lt(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_BOOL(rc == -1);
+}
+
+/* API function: uuid_gt */
+PG_FUNCTION_INFO_V1(pg_uuid_gt);
+Datum pg_uuid_gt(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_BOOL(rc == 1);
+}
+
+/* API function: uuid_le */
+PG_FUNCTION_INFO_V1(pg_uuid_le);
+Datum pg_uuid_le(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_BOOL(rc < 1);
+}
+
+/* API function: uuid_ge */
+PG_FUNCTION_INFO_V1(pg_uuid_ge);
+Datum pg_uuid_ge(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_BOOL(rc > -1);
+}
+
+/* API function: uuid_cmp */
+PG_FUNCTION_INFO_V1(pg_uuid_cmp);
+Datum pg_uuid_cmp(PG_FUNCTION_ARGS)
+{
+ int rc;
+
+ rc = _uuid_cmp(fcinfo);
+ PG_RETURN_INT32(rc);
+}
+
diff --git a/shared/ossp_uuid/pgsql/uuid.sql.in b/shared/ossp_uuid/pgsql/uuid.sql.in
new file mode 100644
index 00000000..c2f01fcc
--- /dev/null
+++ b/shared/ossp_uuid/pgsql/uuid.sql.in
@@ -0,0 +1,244 @@
+--
+-- OSSP uuid - Universally Unique Identifier
+-- Copyright (c) 2004-2007 Ralf S. Engelschall <rse@engelschall.com>
+-- Copyright (c) 2004-2007 The OSSP Project <http://www.ossp.org/>
+--
+-- This file is part of OSSP uuid, a library for the generation
+-- of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/
+--
+-- Permission to use, copy, modify, and distribute this software for
+-- any purpose with or without fee is hereby granted, provided that
+-- the above copyright notice and this permission notice appear in all
+-- copies.
+--
+-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+-- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+-- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+-- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+-- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- uuid.sql: PostgreSQL Binding (SQL part)
+--
+
+--
+-- prolog
+--
+
+SET search_path TO public;
+SET client_min_messages TO warning;
+
+DROP FUNCTION uuid_in(CSTRING) CASCADE;
+DROP FUNCTION uuid_out(uuid) CASCADE;
+DROP FUNCTION uuid_recv(INTERNAL) CASCADE;
+DROP FUNCTION uuid_send(uuid) CASCADE;
+DROP TYPE uuid CASCADE;
+DROP CAST (CSTRING AS uuid) CASCADE;
+DROP CAST (uuid AS CSTRING) CASCADE;
+
+DROP FUNCTION uuid(CSTRING) CASCADE;
+DROP FUNCTION uuid(INTEGER) CASCADE;
+DROP FUNCTION uuid(INTEGER, CSTRING, CSTRING) CASCADE;
+
+DROP FUNCTION uuid_eq(uuid) CASCADE;
+DROP FUNCTION uuid_ne(uuid) CASCADE;
+DROP FUNCTION uuid_lt(uuid, uuid) CASCADE;
+DROP FUNCTION uuid_gt(uuid, uuid) CASCADE;
+DROP FUNCTION uuid_le(uuid, uuid) CASCADE;
+DROP FUNCTION uuid_ge(uuid, uuid) CASCADE;
+DROP OPERATOR =(uuid,uuid) CASCADE;
+DROP OPERATOR <>(uuid,uuid) CASCADE;
+DROP OPERATOR <(uuid,uuid) CASCADE;
+DROP OPERATOR >(uuid,uuid) CASCADE;
+DROP OPERATOR <=(uuid,uuid) CASCADE;
+DROP OPERATOR >=(uuid,uuid) CASCADE;
+
+DROP FUNCTION uuid_hash(uuid) CASCADE;
+DROP FUNCTION uuid_cmp(uuid, uuid) CASCADE;
+DROP OPERATOR CLASS uuid_ops USING hash CASCADE;
+DROP OPERATOR CLASS uuid_ops USING btree CASCADE;
+
+BEGIN;
+
+--
+-- the UUID data type
+--
+
+CREATE FUNCTION
+ uuid_in(CSTRING) RETURNS uuid
+ STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_in';
+
+CREATE FUNCTION
+ uuid_out(uuid) RETURNS CSTRING
+ STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_out';
+
+CREATE FUNCTION
+ uuid_recv(INTERNAL) RETURNS uuid
+ STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_recv';
+
+CREATE FUNCTION
+ uuid_send(uuid) RETURNS BYTEA
+ STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_send';
+
+CREATE TYPE uuid (
+ INPUT = uuid_in, -- for SQL input
+ OUTPUT = uuid_out, -- for SQL output
+ RECEIVE = uuid_recv, -- for DB input
+ SEND = uuid_send, -- for DB output
+ DEFAULT = 'uuid(1)',
+ INTERNALLENGTH = 16,
+ ALIGNMENT = char
+);
+
+COMMENT ON TYPE uuid
+ IS 'UUID type';
+
+-- CREATE CAST (CSTRING AS uuid)
+-- WITH FUNCTION uuid_in(CSTRING) AS ASSIGNMENT;
+--
+-- CREATE CAST (uuid AS CSTRING)
+-- WITH FUNCTION uuid_out(uuid) AS ASSIGNMENT;
+
+--
+-- the UUID constructor function
+--
+
+CREATE FUNCTION
+ uuid(CSTRING) RETURNS uuid
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_in';
+
+CREATE FUNCTION
+ uuid(INTEGER) RETURNS uuid
+ VOLATILE CALLED ON NULL INPUT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_make';
+
+CREATE FUNCTION
+ uuid(INTEGER, CSTRING, CSTRING) RETURNS uuid
+ VOLATILE CALLED ON NULL INPUT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_make';
+
+--
+-- the UUID operators
+--
+
+CREATE FUNCTION
+ uuid_eq(uuid, uuid) RETURNS BOOL
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_eq';
+
+CREATE FUNCTION
+ uuid_ne(uuid, uuid) RETURNS BOOL
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_ne';
+
+CREATE FUNCTION
+ uuid_lt(uuid, uuid) RETURNS BOOL
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_lt';
+
+CREATE FUNCTION
+ uuid_gt(uuid, uuid) RETURNS BOOL
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_gt';
+
+CREATE FUNCTION
+ uuid_le(uuid, uuid) RETURNS BOOL
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_le';
+
+CREATE FUNCTION
+ uuid_ge(uuid, uuid) RETURNS BOOL
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_ge';
+
+CREATE OPERATOR = (
+ leftarg = uuid,
+ rightarg = uuid,
+ negator = <>,
+ procedure = uuid_eq
+);
+
+CREATE OPERATOR <> (
+ leftarg = uuid,
+ rightarg = uuid,
+ negator = =,
+ procedure = uuid_ne
+);
+
+CREATE OPERATOR < (
+ leftarg = uuid,
+ rightarg = uuid,
+ commutator = >,
+ negator = >=,
+ procedure = uuid_lt
+);
+
+CREATE OPERATOR > (
+ leftarg = uuid,
+ rightarg = uuid,
+ commutator = <,
+ negator = <=,
+ procedure = uuid_gt
+);
+
+CREATE OPERATOR <= (
+ leftarg = uuid,
+ rightarg = uuid,
+ commutator = >=,
+ negator = >,
+ procedure = uuid_le
+);
+
+CREATE OPERATOR >= (
+ leftarg = uuid,
+ rightarg = uuid,
+ commutator = <=,
+ negator = <,
+ procedure = uuid_ge
+);
+
+--
+-- the UUID support for indexing
+--
+
+CREATE FUNCTION
+ uuid_hash(uuid) RETURNS INTEGER
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_hash';
+
+CREATE FUNCTION
+ uuid_cmp(uuid, uuid) RETURNS INTEGER
+ IMMUTABLE STRICT
+ LANGUAGE C AS 'MODULE_PATHNAME', 'pg_uuid_cmp';
+
+CREATE OPERATOR CLASS uuid_ops
+ DEFAULT FOR TYPE uuid USING hash AS
+ OPERATOR 1 =, -- 1: equal
+ FUNCTION 1 uuid_hash(uuid);
+
+CREATE OPERATOR CLASS uuid_ops
+ DEFAULT FOR TYPE uuid USING btree AS
+ OPERATOR 1 <, -- 1: less than
+ OPERATOR 2 <=, -- 2: less than or equal
+ OPERATOR 3 =, -- 3: equal
+ OPERATOR 4 >=, -- 4: greater than or equal
+ OPERATOR 5 >, -- 5: greater than
+ FUNCTION 1 uuid_cmp(uuid, uuid);
+
+--
+-- epilog
+--
+
+COMMIT;
+
diff --git a/shared/ossp_uuid/pgsql/uuid.txt b/shared/ossp_uuid/pgsql/uuid.txt
new file mode 100644
index 00000000..c9506de4
--- /dev/null
+++ b/shared/ossp_uuid/pgsql/uuid.txt
@@ -0,0 +1,36 @@
+
+ OSSP uuid bindings for PostgreSQL
+ =================================
+
+ This is the OSSP uuid binding for the PostgreSQL RDBMS, providing
+ native UUID data type support.
+
+ Installation
+ ------------
+
+ In order to install the OSSP uuid binding into the PostgreSQL database
+ <database> one has run:
+
+ $ <prefix>/bin/psql \
+ -d <database> \
+ -U postgresql \
+ -f <prefix>/share/postgresql/uuid.sql
+
+ Usage
+ -----
+
+ psql -d <database>
+ psql> CREATE TABLE test (id UUID DEFAULT uuid(1), name TEXT);
+ psql> INSERT INTO test (name) VALUES
+ ('foo');
+ psql> INSERT INTO test (id, name) VALUES
+ (uuid(1), 'bar');
+ psql> INSERT INTO test (id, name) VALUES
+ (uuid(3, 'ns:URL', 'http://www.ossp.org/'), 'baz');
+ psql> INSERT INTO test (id, name) VALUES
+ (uuid(3, '6ba7b811-9dad-11d1-80b4-00c04fd430c8',
+ 'http://www.ossp.org/'), 'quux');
+ psql> SELECT uuid(4);
+ psql> SELECT * FROM test WHERE id = uuid(3, 'ns:URL', 'http://www.ossp.org/');
+ psql> DROP TABLE test;
+
bgstack15