static void string_to_uuid(const char *str, uuid_t *uuid) { uuid_rc_t rc; rc = uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR + 1); if (rc != UUID_RC_OK) pguuid_complain(rc); }
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)); }
static Datum special_uuid_value(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_load(uuid, 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 char * uuid_to_string(const uuid_t *uuid) { char *buf = palloc(UUID_LEN_STR + 1); void *ptr = buf; size_t len = UUID_LEN_STR + 1; uuid_rc_t rc; rc = uuid_export(uuid, UUID_FMT_STR, &ptr, &len); if (rc != UUID_RC_OK) pguuid_complain(rc); return buf; }
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); return result; }
/* * We create a uuid_t object just once per session and re-use it for all * operations in this module. OSSP UUID caches the system MAC address and * other state in this object. Reusing the object has a number of benefits: * saving the cycles needed to fetch the system MAC address over and over, * reducing the amount of entropy we draw from /dev/urandom, and providing a * positive guarantee that successive generated V1-style UUIDs don't collide. * (On a machine fast enough to generate multiple UUIDs per microsecond, * or whatever the system's wall-clock resolution is, we'd otherwise risk * collisions whenever random initialization of the uuid_t's clock sequence * value chanced to produce duplicates.) * * However: when we're doing V3 or V5 UUID creation, uuid_make needs two * uuid_t objects, one holding the namespace UUID and one for the result. * It's unspecified whether it's safe to use the same uuid_t for both cases, * so let's cache a second uuid_t for use as the namespace holder object. */ static uuid_t * get_cached_uuid_t(int which) { static uuid_t *cached_uuid[2] = {NULL, NULL}; if (cached_uuid[which] == NULL) { uuid_rc_t rc; rc = uuid_create(&cached_uuid[which]); if (rc != UUID_RC_OK) { cached_uuid[which] = NULL; pguuid_complain(rc); } } return cached_uuid[which]; }