aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2014-05-27 19:42:08 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2014-05-27 19:42:08 -0400
commitb8cc8f94730610c0189aa82dfec4ae6ce9b13e34 (patch)
treeaf8422da1b3a204d63aa847a17458e16d4e0c49d
parent616afee14d7e8d6690286aaf8a2a0a01168c378a (diff)
downloadpostgresql-b8cc8f94730610c0189aa82dfec4ae6ce9b13e34.tar.gz
postgresql-b8cc8f94730610c0189aa82dfec4ae6ce9b13e34.zip
Support BSD and e2fsprogs UUID libraries alongside OSSP UUID library.
Allow the contrib/uuid-ossp extension to be built atop any one of these three popular UUID libraries. (The extension's name is now arguably a misnomer, but we'll keep it the same so as not to cause unnecessary compatibility issues for users.) We would not normally consider a change like this post-beta1, but the issue has been forced by our upgrade to autoconf 2.69, whose more rigorous header checks are causing OSSP's header files to be rejected on some platforms. It's been foreseen for some time that we'd have to move away from depending on OSSP UUID due to lack of upstream maintenance, so this is a down payment on that problem. While at it, add some simple regression tests, in hopes of catching any major incompatibilities between the three implementations. Matteo Beccati, with some further hacking by me
-rwxr-xr-xconfigure374
-rw-r--r--configure.in81
-rw-r--r--contrib/Makefile2
-rw-r--r--contrib/uuid-ossp/.gitignore6
-rw-r--r--contrib/uuid-ossp/Makefile16
-rw-r--r--contrib/uuid-ossp/expected/uuid_ossp.out91
-rw-r--r--contrib/uuid-ossp/sql/uuid_ossp.sql22
-rw-r--r--contrib/uuid-ossp/uuid-ossp.c401
-rw-r--r--doc/src/sgml/installation.sgml43
-rw-r--r--doc/src/sgml/uuid-ossp.sgml47
-rw-r--r--src/Makefile.global.in5
-rw-r--r--src/include/pg_config.h.in12
12 files changed, 923 insertions, 177 deletions
diff --git a/configure b/configure
index 17f3f2654f8..3663e50d150 100755
--- a/configure
+++ b/configure
@@ -657,7 +657,7 @@ acx_pthread_config
have_win32_dbghelp
HAVE_IPV6
LIBOBJS
-OSSP_UUID_LIBS
+UUID_LIBS
ZIC
python_enable_shared
python_additional_libs
@@ -705,7 +705,8 @@ with_system_tzdata
with_libxslt
with_libxml
XML2_CONFIG
-with_ossp_uuid
+UUID_EXTRA_OBJS
+with_uuid
with_selinux
with_openssl
krb_srvtab
@@ -826,6 +827,7 @@ with_openssl
with_selinux
with_readline
with_libedit_preferred
+with_uuid
with_ossp_uuid
with_libxml
with_libxslt
@@ -1512,7 +1514,8 @@ Optional Packages:
--without-readline do not use GNU Readline nor BSD Libedit for editing
--with-libedit-preferred
prefer BSD Libedit over GNU Readline
- --with-ossp-uuid build contrib/uuid-ossp, requires OSSP UUID library
+ --with-uuid=LIB build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)
+ --with-ossp-uuid obsolete spelling of --with-uuid=ossp
--with-libxml build with XML support
--with-libxslt use XSLT support when building contrib/xml2
--with-system-tzdata=DIR
@@ -1737,6 +1740,73 @@ fi
} # ac_fn_c_try_cpp
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -2195,73 +2265,6 @@ rm -f conftest.val
} # ac_fn_c_compute_int
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $2 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
# ---------------------------------------------
# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
@@ -5614,11 +5617,40 @@ fi
#
-# OSSP UUID library
+# UUID library
+#
+# There are at least three UUID libraries in common use: the FreeBSD/NetBSD
+# library, the e2fsprogs libuuid (now part of util-linux-ng), and the OSSP
+# UUID library. More than one of these might be present on a given platform,
+# so we make the user say which one she wants.
#
+# Check whether --with-uuid was given.
+if test "${with_uuid+set}" = set; then :
+ withval=$with_uuid;
+ case $withval in
+ yes)
+ as_fn_error $? "argument required for --with-uuid option" "$LINENO" 5
+ ;;
+ no)
+ as_fn_error $? "argument required for --with-uuid option" "$LINENO" 5
+ ;;
+ *)
+
+ ;;
+ esac
+
+fi
+
+
+if test x"$with_uuid" = x"" ; then
+ with_uuid=no
+fi
+
+
+
# Check whether --with-ossp-uuid was given.
if test "${with_ossp_uuid+set}" = set; then :
withval=$with_ossp_uuid;
@@ -5640,6 +5672,31 @@ else
fi
+if test "$with_ossp_uuid" = yes ; then
+ with_uuid=ossp
+fi
+
+if test "$with_uuid" = bsd ; then
+
+$as_echo "#define HAVE_UUID_BSD 1" >>confdefs.h
+
+ UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = e2fs ; then
+
+$as_echo "#define HAVE_UUID_E2FS 1" >>confdefs.h
+
+ UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = ossp ; then
+
+$as_echo "#define HAVE_UUID_OSSP 1" >>confdefs.h
+
+ UUID_EXTRA_OBJS=""
+elif test "$with_uuid" = no ; then
+ UUID_EXTRA_OBJS=""
+else
+ as_fn_error $? "--with-uuid must specify one of bsd, e2fs, or ossp" "$LINENO" 5
+fi
+
@@ -8775,7 +8832,66 @@ fi
fi
# for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
+if test "$with_uuid" = bsd ; then
+ # On BSD, the UUID functions are in libc
+ ac_fn_c_check_func "$LINENO" "uuid_to_string" "ac_cv_func_uuid_to_string"
+if test "x$ac_cv_func_uuid_to_string" = xyes; then :
+ UUID_LIBS=""
+else
+ as_fn_error $? "BSD UUID functions are not present" "$LINENO" 5
+fi
+
+elif test "$with_uuid" = e2fs ; then
+ # On OS X, the UUID functions are in libc
+ ac_fn_c_check_func "$LINENO" "uuid_generate" "ac_cv_func_uuid_generate"
+if test "x$ac_cv_func_uuid_generate" = xyes; then :
+ UUID_LIBS=""
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5
+$as_echo_n "checking for uuid_generate in -luuid... " >&6; }
+if ${ac_cv_lib_uuid_uuid_generate+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_generate ();
+int
+main ()
+{
+return uuid_generate ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_uuid_uuid_generate=yes
+else
+ ac_cv_lib_uuid_uuid_generate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_generate" = xyes; then :
+ UUID_LIBS="-luuid"
+else
+ as_fn_error $? "library 'uuid' is required for E2FS UUID" "$LINENO" 5
+fi
+
+fi
+
+elif test "$with_uuid" = ossp ; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -lossp-uuid" >&5
$as_echo_n "checking for uuid_export in -lossp-uuid... " >&6; }
if ${ac_cv_lib_ossp_uuid_uuid_export+:} false; then :
@@ -8813,7 +8929,7 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ossp_uuid_uuid_export" >&5
$as_echo "$ac_cv_lib_ossp_uuid_uuid_export" >&6; }
if test "x$ac_cv_lib_ossp_uuid_uuid_export" = xyes; then :
- OSSP_UUID_LIBS="-lossp-uuid"
+ UUID_LIBS="-lossp-uuid"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_export in -luuid" >&5
$as_echo_n "checking for uuid_export in -luuid... " >&6; }
@@ -8852,9 +8968,9 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_export" >&5
$as_echo "$ac_cv_lib_uuid_uuid_export" >&6; }
if test "x$ac_cv_lib_uuid_uuid_export" = xyes; then :
- OSSP_UUID_LIBS="-luuid"
+ UUID_LIBS="-luuid"
else
- as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP-UUID" "$LINENO" 5
+ as_fn_error $? "library 'ossp-uuid' or 'uuid' is required for OSSP UUID" "$LINENO" 5
fi
fi
@@ -9398,7 +9514,86 @@ fi
fi
# for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
+if test "$with_uuid" = bsd ; then
+ for ac_header in uuid.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UUID_H 1
+_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uuid_to_string" >/dev/null 2>&1; then :
+
+else
+ as_fn_error $? "header file <uuid.h> does not match BSD UUID library" "$LINENO" 5
+fi
+rm -f conftest*
+
+else
+ as_fn_error $? "header file <uuid.h> is required for BSD UUID" "$LINENO" 5
+fi
+
+done
+
+elif test "$with_uuid" = e2fs ; then
+ for ac_header in uuid/uuid.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_uuid_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UUID_UUID_H 1
+_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <uuid/uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uuid_generate" >/dev/null 2>&1; then :
+
+else
+ as_fn_error $? "header file <uuid/uuid.h> does not match E2FS UUID library" "$LINENO" 5
+fi
+rm -f conftest*
+
+else
+ for ac_header in uuid.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
+if test "x$ac_cv_header_uuid_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_UUID_H 1
+_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uuid_generate" >/dev/null 2>&1; then :
+
+else
+ as_fn_error $? "header file <uuid.h> does not match E2FS UUID library" "$LINENO" 5
+fi
+rm -f conftest*
+
+else
+ as_fn_error $? "header file <uuid/uuid.h> or <uuid.h> is required for E2FS UUID" "$LINENO" 5
+fi
+
+done
+
+fi
+
+done
+
+elif test "$with_uuid" = ossp ; then
for ac_header in ossp/uuid.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "ossp/uuid.h" "ac_cv_header_ossp_uuid_h" "$ac_includes_default"
@@ -9406,19 +9601,42 @@ if test "x$ac_cv_header_ossp_uuid_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_OSSP_UUID_H 1
_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ossp/uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uuid_export" >/dev/null 2>&1; then :
else
+ as_fn_error $? "header file <ossp/uuid.h> does not match OSSP UUID library" "$LINENO" 5
+fi
+rm -f conftest*
- for ac_header in uuid.h
+else
+ for ac_header in uuid.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default"
if test "x$ac_cv_header_uuid_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_UUID_H 1
_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <uuid.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "uuid_export" >/dev/null 2>&1; then :
+
+else
+ as_fn_error $? "header file <uuid.h> does not match OSSP UUID library" "$LINENO" 5
+fi
+rm -f conftest*
else
- as_fn_error $? "header file <ossp/uuid.h> or <uuid.h> is required for OSSP-UUID" "$LINENO" 5
+ as_fn_error $? "header file <ossp/uuid.h> or <uuid.h> is required for OSSP UUID" "$LINENO" 5
fi
done
diff --git a/configure.in b/configure.in
index b94db352e13..80df1d76510 100644
--- a/configure.in
+++ b/configure.in
@@ -694,10 +694,38 @@ PGAC_ARG_BOOL(with, libedit-preferred, no,
#
-# OSSP UUID library
+# UUID library
#
-PGAC_ARG_BOOL(with, ossp-uuid, no, [build contrib/uuid-ossp, requires OSSP UUID library])
-AC_SUBST(with_ossp_uuid)
+# There are at least three UUID libraries in common use: the FreeBSD/NetBSD
+# library, the e2fsprogs libuuid (now part of util-linux-ng), and the OSSP
+# UUID library. More than one of these might be present on a given platform,
+# so we make the user say which one she wants.
+#
+PGAC_ARG_REQ(with, uuid, [LIB], [build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)])
+if test x"$with_uuid" = x"" ; then
+ with_uuid=no
+fi
+PGAC_ARG_BOOL(with, ossp-uuid, no, [obsolete spelling of --with-uuid=ossp])
+if test "$with_ossp_uuid" = yes ; then
+ with_uuid=ossp
+fi
+
+if test "$with_uuid" = bsd ; then
+ AC_DEFINE([HAVE_UUID_BSD], 1, [Define to 1 if you have BSD UUID support.])
+ UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = e2fs ; then
+ AC_DEFINE([HAVE_UUID_E2FS], 1, [Define to 1 if you have E2FS UUID support.])
+ UUID_EXTRA_OBJS="md5.o sha1.o"
+elif test "$with_uuid" = ossp ; then
+ AC_DEFINE([HAVE_UUID_OSSP], 1, [Define to 1 if you have OSSP UUID support.])
+ UUID_EXTRA_OBJS=""
+elif test "$with_uuid" = no ; then
+ UUID_EXTRA_OBJS=""
+else
+ AC_MSG_ERROR([--with-uuid must specify one of bsd, e2fs, or ossp])
+fi
+AC_SUBST(with_uuid)
+AC_SUBST(UUID_EXTRA_OBJS)
#
@@ -948,14 +976,26 @@ if test "$with_selinux" = yes; then
fi
# for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
+if test "$with_uuid" = bsd ; then
+ # On BSD, the UUID functions are in libc
+ AC_CHECK_FUNC(uuid_to_string,
+ [UUID_LIBS=""],
+ [AC_MSG_ERROR([BSD UUID functions are not present])])
+elif test "$with_uuid" = e2fs ; then
+ # On OS X, the UUID functions are in libc
+ AC_CHECK_FUNC(uuid_generate,
+ [UUID_LIBS=""],
+ [AC_CHECK_LIB(uuid, uuid_generate,
+ [UUID_LIBS="-luuid"],
+ [AC_MSG_ERROR([library 'uuid' is required for E2FS UUID])])])
+elif test "$with_uuid" = ossp ; then
AC_CHECK_LIB(ossp-uuid, uuid_export,
- [OSSP_UUID_LIBS="-lossp-uuid"],
+ [UUID_LIBS="-lossp-uuid"],
[AC_CHECK_LIB(uuid, uuid_export,
- [OSSP_UUID_LIBS="-luuid"],
- [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP-UUID])])])
+ [UUID_LIBS="-luuid"],
+ [AC_MSG_ERROR([library 'ossp-uuid' or 'uuid' is required for OSSP UUID])])])
fi
-AC_SUBST(OSSP_UUID_LIBS)
+AC_SUBST(UUID_LIBS)
##
@@ -1075,10 +1115,27 @@ if test "$with_bonjour" = yes ; then
fi
# for contrib/uuid-ossp
-if test "$with_ossp_uuid" = yes ; then
- AC_CHECK_HEADERS(ossp/uuid.h, [], [
- AC_CHECK_HEADERS(uuid.h, [],
- [AC_MSG_ERROR([header file <ossp/uuid.h> or <uuid.h> is required for OSSP-UUID])])])
+if test "$with_uuid" = bsd ; then
+ AC_CHECK_HEADERS(uuid.h,
+ [AC_EGREP_HEADER([uuid_to_string], uuid.h, [],
+ [AC_MSG_ERROR([header file <uuid.h> does not match BSD UUID library])])],
+ [AC_MSG_ERROR([header file <uuid.h> is required for BSD UUID])])
+elif test "$with_uuid" = e2fs ; then
+ AC_CHECK_HEADERS(uuid/uuid.h,
+ [AC_EGREP_HEADER([uuid_generate], uuid/uuid.h, [],
+ [AC_MSG_ERROR([header file <uuid/uuid.h> does not match E2FS UUID library])])],
+ [AC_CHECK_HEADERS(uuid.h,
+ [AC_EGREP_HEADER([uuid_generate], uuid.h, [],
+ [AC_MSG_ERROR([header file <uuid.h> does not match E2FS UUID library])])],
+ [AC_MSG_ERROR([header file <uuid/uuid.h> or <uuid.h> is required for E2FS UUID])])])
+elif test "$with_uuid" = ossp ; then
+ AC_CHECK_HEADERS(ossp/uuid.h,
+ [AC_EGREP_HEADER([uuid_export], ossp/uuid.h, [],
+ [AC_MSG_ERROR([header file <ossp/uuid.h> does not match OSSP UUID library])])],
+ [AC_CHECK_HEADERS(uuid.h,
+ [AC_EGREP_HEADER([uuid_export], uuid.h, [],
+ [AC_MSG_ERROR([header file <uuid.h> does not match OSSP UUID library])])],
+ [AC_MSG_ERROR([header file <ossp/uuid.h> or <uuid.h> is required for OSSP UUID])])])
fi
if test "$PORTNAME" = "win32" ; then
diff --git a/contrib/Makefile b/contrib/Makefile
index 8dc40f7de00..b37d0dd2c31 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -64,7 +64,7 @@ else
ALWAYS_SUBDIRS += sslinfo
endif
-ifeq ($(with_ossp_uuid),yes)
+ifneq ($(with_uuid),no)
SUBDIRS += uuid-ossp
else
ALWAYS_SUBDIRS += uuid-ossp
diff --git a/contrib/uuid-ossp/.gitignore b/contrib/uuid-ossp/.gitignore
new file mode 100644
index 00000000000..6c989c78729
--- /dev/null
+++ b/contrib/uuid-ossp/.gitignore
@@ -0,0 +1,6 @@
+/md5.c
+/sha1.c
+# Generated subdirectories
+/log/
+/results/
+/tmp_check/
diff --git a/contrib/uuid-ossp/Makefile b/contrib/uuid-ossp/Makefile
index 9b2d2e3ff93..335cc7ef50a 100644
--- a/contrib/uuid-ossp/Makefile
+++ b/contrib/uuid-ossp/Makefile
@@ -1,12 +1,21 @@
# contrib/uuid-ossp/Makefile
MODULE_big = uuid-ossp
-OBJS = uuid-ossp.o
+OBJS = uuid-ossp.o $(UUID_EXTRA_OBJS)
EXTENSION = uuid-ossp
DATA = uuid-ossp--1.0.sql uuid-ossp--unpackaged--1.0.sql
-SHLIB_LINK += $(OSSP_UUID_LIBS)
+REGRESS = uuid_ossp
+
+SHLIB_LINK += $(UUID_LIBS)
+
+# We copy some needed files verbatim from pgcrypto
+pgcrypto_src = $(top_srcdir)/contrib/pgcrypto
+
+PG_CPPFLAGS = -I$(pgcrypto_src)
+
+EXTRA_CLEAN = md5.c sha1.c
ifdef USE_PGXS
PG_CONFIG = pg_config
@@ -18,3 +27,6 @@ top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
+
+md5.c sha1.c: % : $(pgcrypto_src)/%
+ rm -f $@ && $(LN_S) $< .
diff --git a/contrib/uuid-ossp/expected/uuid_ossp.out b/contrib/uuid-ossp/expected/uuid_ossp.out
new file mode 100644
index 00000000000..986843c8976
--- /dev/null
+++ b/contrib/uuid-ossp/expected/uuid_ossp.out
@@ -0,0 +1,91 @@
+CREATE EXTENSION "uuid-ossp";
+SELECT uuid_nil();
+ uuid_nil
+--------------------------------------
+ 00000000-0000-0000-0000-000000000000
+(1 row)
+
+SELECT uuid_ns_dns();
+ uuid_ns_dns
+--------------------------------------
+ 6ba7b810-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_url();
+ uuid_ns_url
+--------------------------------------
+ 6ba7b811-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_oid();
+ uuid_ns_oid
+--------------------------------------
+ 6ba7b812-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_ns_x500();
+ uuid_ns_x500
+--------------------------------------
+ 6ba7b814-9dad-11d1-80b4-00c04fd430c8
+(1 row)
+
+SELECT uuid_generate_v1() < uuid_generate_v1();
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT uuid_generate_v1() < uuid_generate_v1mc();
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25);
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT ('x' || substr(uuid_generate_v1mc()::text, 25, 2))::bit(8) & '00000011';
+ ?column?
+----------
+ 00000011
+(1 row)
+
+SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+ uuid_generate_v3
+--------------------------------------
+ 3d813cbb-47fb-32ba-91df-831e1593ac29
+(1 row)
+
+SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+ uuid_generate_v5
+--------------------------------------
+ 21f7f8de-8051-5b89-8680-0195ef798b6a
+(1 row)
+
+SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$';
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT uuid_generate_v4() <> uuid_generate_v4();
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/contrib/uuid-ossp/sql/uuid_ossp.sql b/contrib/uuid-ossp/sql/uuid_ossp.sql
new file mode 100644
index 00000000000..29fba21b3f7
--- /dev/null
+++ b/contrib/uuid-ossp/sql/uuid_ossp.sql
@@ -0,0 +1,22 @@
+CREATE EXTENSION "uuid-ossp";
+
+SELECT uuid_nil();
+SELECT uuid_ns_dns();
+SELECT uuid_ns_url();
+SELECT uuid_ns_oid();
+SELECT uuid_ns_x500();
+
+SELECT uuid_generate_v1() < uuid_generate_v1();
+SELECT uuid_generate_v1() < uuid_generate_v1mc();
+
+SELECT substr(uuid_generate_v1()::text, 25) = substr(uuid_generate_v1()::text, 25);
+SELECT substr(uuid_generate_v1()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+SELECT substr(uuid_generate_v1mc()::text, 25) <> substr(uuid_generate_v1mc()::text, 25);
+
+SELECT ('x' || substr(uuid_generate_v1mc()::text, 25, 2))::bit(8) & '00000011';
+
+SELECT uuid_generate_v3(uuid_ns_dns(), 'www.widgets.com');
+SELECT uuid_generate_v5(uuid_ns_dns(), 'www.widgets.com');
+
+SELECT uuid_generate_v4()::text ~ '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$';
+SELECT uuid_generate_v4() <> uuid_generate_v4();
diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c
index 8f99084df34..f8c33d2b469 100644
--- a/contrib/uuid-ossp/uuid-ossp.c
+++ b/contrib/uuid-ossp/uuid-ossp.c
@@ -1,40 +1,113 @@
/*-------------------------------------------------------------------------
*
- * UUID generation functions using the OSSP UUID library
+ * UUID generation functions using the BSD, E2FS or OSSP UUID library
*
* Copyright (c) 2007-2014, PostgreSQL Global Development Group
*
+ * Portions Copyright (c) 2009 Andrew Gierth
+ *
* contrib/uuid-ossp/uuid-ossp.c
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+
#include "fmgr.h"
#include "utils/builtins.h"
#include "utils/uuid.h"
/*
- * There's some confusion over the location of the uuid.h header file.
- * On Debian, it's installed as ossp/uuid.h, while on Fedora, or if you
- * install ossp-uuid from a tarball, it's installed as uuid.h. Don't know
- * what other systems do.
+ * It's possible that there's more than one uuid.h header file present.
+ * We expect configure to set the HAVE_ symbol for only the one we want.
+ *
+ * BSD includes a uuid_hash() function that conflicts with the one in
+ * builtins.h; we #define it out of the way.
*/
-#ifdef HAVE_OSSP_UUID_H
-#include <ossp/uuid.h>
-#else
+#define uuid_hash bsd_uuid_hash
+
#ifdef HAVE_UUID_H
#include <uuid.h>
-#else
-#error OSSP uuid.h not found
#endif
+#ifdef HAVE_OSSP_UUID_H
+#include <ossp/uuid.h>
#endif
+#ifdef HAVE_UUID_UUID_H
+#include <uuid/uuid.h>
+#endif
+
+#undef uuid_hash
-/* better both be 16 */
-#if (UUID_LEN != UUID_LEN_BIN)
+/*
+ * Some BSD variants offer md5 and sha1 implementations but Linux does not,
+ * so we use a copy of the ones from pgcrypto. Not needed with OSSP, though.
+ */
+#ifndef HAVE_UUID_OSSP
+#include "md5.h"
+#include "sha1.h"
+#endif
+
+
+/* Check our UUID length against OSSP's; better both be 16 */
+#if defined(HAVE_UUID_OSSP) && (UUID_LEN != UUID_LEN_BIN)
#error UUID length mismatch
#endif
+/* Define some constants like OSSP's, to make the code more readable */
+#ifndef HAVE_UUID_OSSP
+#define UUID_MAKE_MC 0
+#define UUID_MAKE_V1 1
+#define UUID_MAKE_V2 2
+#define UUID_MAKE_V3 3
+#define UUID_MAKE_V4 4
+#define UUID_MAKE_V5 5
+#endif
+
+/*
+ * A DCE 1.1 compatible source representation of UUIDs, derived from
+ * the BSD implementation. BSD already has this; OSSP doesn't need it.
+ */
+#ifdef HAVE_UUID_E2FS
+typedef struct
+{
+ uint32_t time_low;
+ uint16_t time_mid;
+ uint16_t time_hi_and_version;
+ uint8_t clock_seq_hi_and_reserved;
+ uint8_t clock_seq_low;
+ uint8_t node[6];
+} dce_uuid_t;
+#else
+#define dce_uuid_t uuid_t
+#endif
+
+/* If not OSSP, we need some endianness-manipulation macros */
+#ifndef HAVE_UUID_OSSP
+
+#define UUID_TO_NETWORK(uu) \
+do { \
+ uu.time_low = htonl(uu.time_low); \
+ uu.time_mid = htons(uu.time_mid); \
+ uu.time_hi_and_version = htons(uu.time_hi_and_version); \
+} while (0)
+
+#define UUID_TO_LOCAL(uu) \
+do { \
+ uu.time_low = ntohl(uu.time_low); \
+ uu.time_mid = ntohs(uu.time_mid); \
+ uu.time_hi_and_version = ntohs(uu.time_hi_and_version); \
+} while (0)
+
+#define UUID_V3_OR_V5(uu, v) \
+do { \
+ uu.time_hi_and_version &= 0x0FFF; \
+ uu.time_hi_and_version |= (v << 12); \
+ uu.clock_seq_hi_and_reserved &= 0x3F; \
+ uu.clock_seq_hi_and_reserved |= 0x80; \
+} while(0)
+
+#endif /* !HAVE_UUID_OSSP */
+
PG_MODULE_MAGIC;
@@ -51,6 +124,8 @@ PG_FUNCTION_INFO_V1(uuid_generate_v3);
PG_FUNCTION_INFO_V1(uuid_generate_v4);
PG_FUNCTION_INFO_V1(uuid_generate_v5);
+#ifdef HAVE_UUID_OSSP
+
static void
pguuid_complain(uuid_rc_t rc)
{
@@ -114,100 +189,294 @@ special_uuid_value(const char *name)
return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
}
+/* len is unused with OSSP, but we want to have the same number of args */
+static Datum
+uuid_generate_internal(int mode, const uuid_t *ns, const char *name, int len)
+{
+ uuid_t *uuid;
+ char *str;
+ uuid_rc_t rc;
+
+ rc = uuid_create(&uuid);
+ if (rc != UUID_RC_OK)
+ pguuid_complain(rc);
+ rc = uuid_make(uuid, mode, ns, name);
+ if (rc != UUID_RC_OK)
+ pguuid_complain(rc);
+ str = uuid_to_string(uuid);
+ rc = uuid_destroy(uuid);
+ if (rc != UUID_RC_OK)
+ pguuid_complain(rc);
+
+ return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
+}
+
+
+static Datum
+uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
+{
+ uuid_t *ns_uuid;
+ Datum result;
+ uuid_rc_t rc;
+
+ rc = uuid_create(&ns_uuid);
+ if (rc != UUID_RC_OK)
+ pguuid_complain(rc);
+ string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
+ ns_uuid);
+
+ result = uuid_generate_internal(mode,
+ ns_uuid,
+ text_to_cstring(name),
+ 0);
+
+ rc = uuid_destroy(ns_uuid);
+ if (rc != UUID_RC_OK)
+ pguuid_complain(rc);
+
+ return result;
+}
+
+#else /* !HAVE_UUID_OSSP */
+
+static Datum
+uuid_generate_internal(int v, unsigned char *ns, char *ptr, int len)
+{
+ char strbuf[40];
+
+ switch (v)
+ {
+ case 0: /* constant-value uuids */
+ strlcpy(strbuf, ptr, 37);
+ break;
+
+ case 1: /* time/node-based uuids */
+ {
+#ifdef HAVE_UUID_E2FS
+ uuid_t uu;
+
+ uuid_generate_time(uu);
+ uuid_unparse(uu, strbuf);
+
+ /*
+ * PTR, if set, replaces the trailing characters of the uuid;
+ * this is to support v1mc, where a random multicast MAC is
+ * used instead of the physical one
+ */
+ if (ptr && len <= 36)
+ strcpy(strbuf + (36 - len), ptr);
+#else /* BSD */
+ uuid_t uu;
+ uint32_t status = uuid_s_ok;
+ char *str = NULL;
+
+ uuid_create(&uu, &status);
+
+ if (status == uuid_s_ok)
+ {
+ uuid_to_string(&uu, &str, &status);
+ if (status == uuid_s_ok)
+ {
+ strlcpy(strbuf, str, 37);
+
+ /*
+ * PTR, if set, replaces the trailing characters of
+ * the uuid; this is to support v1mc, where a random
+ * multicast MAC is used instead of the physical one
+ */
+ if (ptr && len <= 36)
+ strcpy(strbuf + (36 - len), ptr);
+ }
+ if (str)
+ free(str);
+ }
+
+ if (status != uuid_s_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
+ errmsg("uuid library failure: %d",
+ (int) status)));
+#endif
+ break;
+ }
+
+ case 3: /* namespace-based MD5 uuids */
+ case 5: /* namespace-based SHA1 uuids */
+ {
+ dce_uuid_t uu;
+#ifdef HAVE_UUID_BSD
+ uint32_t status = uuid_s_ok;
+ char *str = NULL;
+#endif
+
+ if (v == 3)
+ {
+ MD5_CTX ctx;
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, ns, sizeof(uu));
+ MD5Update(&ctx, (unsigned char *) ptr, len);
+ MD5Final((unsigned char *) &uu, &ctx);
+ }
+ else
+ {
+ SHA1_CTX ctx;
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, ns, sizeof(uu));
+ SHA1Update(&ctx, (unsigned char *) ptr, len);
+ SHA1Final((unsigned char *) &uu, &ctx);
+ }
+
+ /* the calculated hash is using local order */
+ UUID_TO_NETWORK(uu);
+ UUID_V3_OR_V5(uu, v);
+
+#ifdef HAVE_UUID_E2FS
+ /* uuid_unparse expects local order */
+ UUID_TO_LOCAL(uu);
+ uuid_unparse((unsigned char *) &uu, strbuf);
+#else /* BSD */
+ uuid_to_string(&uu, &str, &status);
+
+ if (status == uuid_s_ok)
+ strlcpy(strbuf, str, 37);
+
+ if (str)
+ free(str);
+
+ if (status != uuid_s_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
+ errmsg("uuid library failure: %d",
+ (int) status)));
+#endif
+ break;
+ }
+
+ case 4: /* random uuid */
+ default:
+ {
+#ifdef HAVE_UUID_E2FS
+ uuid_t uu;
+
+ uuid_generate_random(uu);
+ uuid_unparse(uu, strbuf);
+#else /* BSD */
+ snprintf(strbuf, sizeof(strbuf),
+ "%08lx-%04x-%04x-%04x-%04x%08lx",
+ (unsigned long) arc4random(),
+ (unsigned) (arc4random() & 0xffff),
+ (unsigned) ((arc4random() & 0xfff) | 0x4000),
+ (unsigned) ((arc4random() & 0x3fff) | 0x8000),
+ (unsigned) (arc4random() & 0xffff),
+ (unsigned long) arc4random());
+#endif
+ break;
+ }
+ }
+
+ return DirectFunctionCall1(uuid_in, CStringGetDatum(strbuf));
+}
+
+#endif /* HAVE_UUID_OSSP */
+
Datum
uuid_nil(PG_FUNCTION_ARGS)
{
+#ifdef HAVE_UUID_OSSP
return special_uuid_value("nil");
+#else
+ return uuid_generate_internal(0, NULL,
+ "00000000-0000-0000-0000-000000000000", 36);
+#endif
}
Datum
uuid_ns_dns(PG_FUNCTION_ARGS)
{
+#ifdef HAVE_UUID_OSSP
return special_uuid_value("ns:DNS");
+#else
+ return uuid_generate_internal(0, NULL,
+ "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
}
Datum
uuid_ns_url(PG_FUNCTION_ARGS)
{
+#ifdef HAVE_UUID_OSSP
return special_uuid_value("ns:URL");
+#else
+ return uuid_generate_internal(0, NULL,
+ "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
}
Datum
uuid_ns_oid(PG_FUNCTION_ARGS)
{
+#ifdef HAVE_UUID_OSSP
return special_uuid_value("ns:OID");
+#else
+ return uuid_generate_internal(0, NULL,
+ "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
}
Datum
uuid_ns_x500(PG_FUNCTION_ARGS)
{
+#ifdef HAVE_UUID_OSSP
return special_uuid_value("ns:X500");
-}
-
-
-static Datum
-uuid_generate_internal(int mode, const uuid_t *ns, const char *name)
-{
- uuid_t *uuid;
- char *str;
- uuid_rc_t rc;
-
- rc = uuid_create(&uuid);
- if (rc != UUID_RC_OK)
- pguuid_complain(rc);
- rc = uuid_make(uuid, mode, ns, name);
- if (rc != UUID_RC_OK)
- pguuid_complain(rc);
- str = uuid_to_string(uuid);
- rc = uuid_destroy(uuid);
- if (rc != UUID_RC_OK)
- pguuid_complain(rc);
-
- return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
+#else
+ return uuid_generate_internal(0, NULL,
+ "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 36);
+#endif
}
Datum
uuid_generate_v1(PG_FUNCTION_ARGS)
{
- return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL);
+ return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL, 0);
}
Datum
uuid_generate_v1mc(PG_FUNCTION_ARGS)
{
- return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL);
-}
-
-
-static Datum
-uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
-{
- uuid_t *ns_uuid;
- Datum result;
- uuid_rc_t rc;
-
- rc = uuid_create(&ns_uuid);
- if (rc != UUID_RC_OK)
- pguuid_complain(rc);
- string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
- ns_uuid);
-
- result = uuid_generate_internal(mode,
- ns_uuid,
- text_to_cstring(name));
-
- rc = uuid_destroy(ns_uuid);
- if (rc != UUID_RC_OK)
- pguuid_complain(rc);
+#ifdef HAVE_UUID_OSSP
+ char *buf = NULL;
+#elif defined(HAVE_UUID_E2FS)
+ char strbuf[40];
+ char *buf;
+ uuid_t uu;
+
+ uuid_generate_random(uu);
+
+ /* set IEEE802 multicast and local-admin bits */
+ ((dce_uuid_t *) &uu)->node[0] |= 0x03;
+
+ uuid_unparse(uu, strbuf);
+ buf = strbuf + 24;
+#else /* BSD */
+ char buf[16];
+
+ /* set IEEE802 multicast and local-admin bits */
+ snprintf(buf, sizeof(buf), "-%04x%08lx",
+ (unsigned) ((arc4random() & 0xffff) | 0x0300),
+ (unsigned long) arc4random());
+#endif
- return result;
+ return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL,
+ buf, 13);
}
@@ -217,14 +486,19 @@ uuid_generate_v3(PG_FUNCTION_ARGS)
pg_uuid_t *ns = PG_GETARG_UUID_P(0);
text *name = PG_GETARG_TEXT_P(1);
+#ifdef HAVE_UUID_OSSP
return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name);
+#else
+ return uuid_generate_internal(UUID_MAKE_V3, (unsigned char *) ns,
+ VARDATA(name), VARSIZE(name) - VARHDRSZ);
+#endif
}
Datum
uuid_generate_v4(PG_FUNCTION_ARGS)
{
- return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL);
+ return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL, 0);
}
@@ -234,5 +508,10 @@ uuid_generate_v5(PG_FUNCTION_ARGS)
pg_uuid_t *ns = PG_GETARG_UUID_P(0);
text *name = PG_GETARG_TEXT_P(1);
+#ifdef HAVE_UUID_OSSP
return uuid_generate_v35_internal(UUID_MAKE_V5, ns, name);
+#else
+ return uuid_generate_internal(UUID_MAKE_V5, (unsigned char *) ns,
+ VARDATA(name), VARSIZE(name) - VARHDRSZ);
+#endif
}
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index b6b582e24c2..7353c612b1f 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -870,16 +870,45 @@ su - postgres
</varlistentry>
<varlistentry>
+ <term><option>--with-uuid=<replaceable>LIBRARY</replaceable></option></term>
+ <listitem>
+ <para>
+ Build the <![%standalone-include[uuid-ossp]]>
+ <![%standalone-ignore[<xref linkend="uuid-ossp">]]> module
+ (which provides functions to generate UUIDs), using the specified
+ UUID library.<indexterm><primary>UUID</primary></indexterm>
+ <replaceable>LIBRARY</replaceable> must be one of:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <option>bsd</> to use the UUID functions found in FreeBSD, NetBSD,
+ and some other BSD-derived systems
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <option>e2fs</> to use the UUID library created by
+ the <literal>e2fsprogs</> project; this library is present in most
+ Linux systems and in Mac OS X, and can be obtained for other
+ platforms as well
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <option>ossp</> to use the <ulink
+ url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID library</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--with-ossp-uuid</option></term>
<listitem>
<para>
- Build components using the <ulink
- url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID
- library</ulink>. Specifically, build the
- <![%standalone-include[uuid-ossp]]>
- <![%standalone-ignore[<xref linkend="uuid-ossp">]]> module,
- which provides functions to generate
- UUIDs.<indexterm><primary>UUID</primary></indexterm>
+ Obsolete equivalent of <literal>--with-uuid=ossp</literal>.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/uuid-ossp.sgml b/doc/src/sgml/uuid-ossp.sgml
index c48106ba0f4..dbbea09313a 100644
--- a/doc/src/sgml/uuid-ossp.sgml
+++ b/doc/src/sgml/uuid-ossp.sgml
@@ -13,20 +13,6 @@
are also functions to produce certain special UUID constants.
</para>
- <para>
- This module depends on the OSSP UUID library, which can be found at
- <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>
@@ -173,6 +159,39 @@ SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org');
</sect2>
<sect2>
+ <title>Building <filename>uuid-ossp</></title>
+
+ <para>
+ Historically this module depended on the OSSP UUID library, which accounts
+ for the module's name. While the OSSP UUID library can still be found
+ at <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>, it is not well
+ maintained, and is becoming increasingly difficult to port to newer
+ platforms. <filename>uuid-ossp</> can now be built without the OSSP
+ library on some platforms. On FreeBSD, NetBSD, and some other BSD-derived
+ platforms, suitable UUID creation functions are included in the
+ core <filename>libc</> library. On Linux, Mac OS X, and some other
+ platforms, suitable functions are provided in the <filename>libuuid</>
+ library, which originally came from the <literal>e2fsprogs</> project
+ (though on modern Linux it is considered part
+ of <literal>util-linux-ng</>). When invoking <filename>configure</>,
+ specify <option>--with-uuid=bsd</option> to use the BSD functions,
+ or <option>--with-uuid=e2fs</option> to
+ use <literal>e2fsprogs</>' <filename>libuuid</>, or
+ <option>--with-uuid=ossp</option> to use the OSSP UUID library.
+ More than one of these libraries might be available on a particular
+ machine, so <filename>configure</> does not automatically choose one.
+ </para>
+
+ <note>
+ <para>
+ 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>Author</title>
<para>
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 4b31c0a85e6..14119a15115 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -163,11 +163,11 @@ with_perl = @with_perl@
with_python = @with_python@
with_tcl = @with_tcl@
with_openssl = @with_openssl@
-with_ossp_uuid = @with_ossp_uuid@
with_selinux = @with_selinux@
with_libxml = @with_libxml@
with_libxslt = @with_libxslt@
with_system_tzdata = @with_system_tzdata@
+with_uuid = @with_uuid@
with_zlib = @with_zlib@
enable_rpath = @enable_rpath@
enable_nls = @enable_nls@
@@ -240,7 +240,8 @@ DLLWRAP = @DLLWRAP@
LIBS = @LIBS@
LDAP_LIBS_FE = @LDAP_LIBS_FE@
LDAP_LIBS_BE = @LDAP_LIBS_BE@
-OSSP_UUID_LIBS = @OSSP_UUID_LIBS@
+UUID_LIBS = @UUID_LIBS@
+UUID_EXTRA_OBJS = @UUID_EXTRA_OBJS@
LD = @LD@
with_gnu_ld = @with_gnu_ld@
ld_R_works = @ld_R_works@
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index db930f5bb0e..5ff9e412121 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -602,9 +602,21 @@
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
+/* Define to 1 if you have BSD UUID support. */
+#undef HAVE_UUID_BSD
+
+/* Define to 1 if you have E2FS UUID support. */
+#undef HAVE_UUID_E2FS
+
/* Define to 1 if you have the <uuid.h> header file. */
#undef HAVE_UUID_H
+/* Define to 1 if you have OSSP UUID support. */
+#undef HAVE_UUID_OSSP
+
+/* Define to 1 if you have the <uuid/uuid.h> header file. */
+#undef HAVE_UUID_UUID_H
+
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF