1 /*-------------------------------------------------------------------------
3 * UUID generation functions using the OSSP UUID library
5 * Copyright (c) 2007-2008 PostgreSQL Global Development Group
9 *-------------------------------------------------------------------------
14 #include "utils/builtins.h"
15 #include "utils/uuid.h"
18 * There's some confusion over the location of the uuid.h header file.
19 * On Debian, it's installed as ossp/uuid.h, while on Fedora, or if you
20 * install ossp-uuid from a tarball, it's installed as uuid.h. Don't know
21 * what other systems do.
23 #ifdef HAVE_OSSP_UUID_H
24 #include <ossp/uuid.h>
29 #error OSSP uuid.h not found
33 /* better both be 16 */
34 #if (UUID_LEN != UUID_LEN_BIN)
35 #error UUID length mismatch
42 Datum
uuid_nil(PG_FUNCTION_ARGS
);
43 Datum
uuid_ns_dns(PG_FUNCTION_ARGS
);
44 Datum
uuid_ns_url(PG_FUNCTION_ARGS
);
45 Datum
uuid_ns_oid(PG_FUNCTION_ARGS
);
46 Datum
uuid_ns_x500(PG_FUNCTION_ARGS
);
48 Datum
uuid_generate_v1(PG_FUNCTION_ARGS
);
49 Datum
uuid_generate_v1mc(PG_FUNCTION_ARGS
);
50 Datum
uuid_generate_v3(PG_FUNCTION_ARGS
);
51 Datum
uuid_generate_v4(PG_FUNCTION_ARGS
);
52 Datum
uuid_generate_v5(PG_FUNCTION_ARGS
);
55 PG_FUNCTION_INFO_V1(uuid_nil
);
56 PG_FUNCTION_INFO_V1(uuid_ns_dns
);
57 PG_FUNCTION_INFO_V1(uuid_ns_url
);
58 PG_FUNCTION_INFO_V1(uuid_ns_oid
);
59 PG_FUNCTION_INFO_V1(uuid_ns_x500
);
61 PG_FUNCTION_INFO_V1(uuid_generate_v1
);
62 PG_FUNCTION_INFO_V1(uuid_generate_v1mc
);
63 PG_FUNCTION_INFO_V1(uuid_generate_v3
);
64 PG_FUNCTION_INFO_V1(uuid_generate_v4
);
65 PG_FUNCTION_INFO_V1(uuid_generate_v5
);
68 pguuid_complain(uuid_rc_t rc
)
70 char *err
= uuid_error(rc
);
74 (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION
),
75 errmsg("OSSP uuid library failure: %s", err
)));
78 (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION
),
79 errmsg("OSSP uuid library failure: error code %d", rc
)));
83 uuid_to_string(const uuid_t
* uuid
)
85 char *buf
= palloc(UUID_LEN_STR
+ 1);
87 size_t len
= UUID_LEN_STR
+ 1;
90 rc
= uuid_export(uuid
, UUID_FMT_STR
, &ptr
, &len
);
99 string_to_uuid(const char *str
, uuid_t
* uuid
)
103 rc
= uuid_import(uuid
, UUID_FMT_STR
, str
, UUID_LEN_STR
+ 1);
104 if (rc
!= UUID_RC_OK
)
110 special_uuid_value(const char *name
)
116 rc
= uuid_create(&uuid
);
117 if (rc
!= UUID_RC_OK
)
119 rc
= uuid_load(uuid
, name
);
120 if (rc
!= UUID_RC_OK
)
122 str
= uuid_to_string(uuid
);
123 rc
= uuid_destroy(uuid
);
124 if (rc
!= UUID_RC_OK
)
127 return DirectFunctionCall1(uuid_in
, CStringGetDatum(str
));
132 uuid_nil(PG_FUNCTION_ARGS
)
134 return special_uuid_value("nil");
139 uuid_ns_dns(PG_FUNCTION_ARGS
)
141 return special_uuid_value("ns:DNS");
146 uuid_ns_url(PG_FUNCTION_ARGS
)
148 return special_uuid_value("ns:URL");
153 uuid_ns_oid(PG_FUNCTION_ARGS
)
155 return special_uuid_value("ns:OID");
160 uuid_ns_x500(PG_FUNCTION_ARGS
)
162 return special_uuid_value("ns:X500");
167 uuid_generate_internal(int mode
, const uuid_t
* ns
, const char *name
)
173 rc
= uuid_create(&uuid
);
174 if (rc
!= UUID_RC_OK
)
176 rc
= uuid_make(uuid
, mode
, ns
, name
);
177 if (rc
!= UUID_RC_OK
)
179 str
= uuid_to_string(uuid
);
180 rc
= uuid_destroy(uuid
);
181 if (rc
!= UUID_RC_OK
)
184 return DirectFunctionCall1(uuid_in
, CStringGetDatum(str
));
189 uuid_generate_v1(PG_FUNCTION_ARGS
)
191 return uuid_generate_internal(UUID_MAKE_V1
, NULL
, NULL
);
196 uuid_generate_v1mc(PG_FUNCTION_ARGS
)
198 return uuid_generate_internal(UUID_MAKE_V1
| UUID_MAKE_MC
, NULL
, NULL
);
203 uuid_generate_v35_internal(int mode
, pg_uuid_t
*ns
, text
*name
)
209 rc
= uuid_create(&ns_uuid
);
210 if (rc
!= UUID_RC_OK
)
212 string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out
, UUIDPGetDatum(ns
))),
215 result
= uuid_generate_internal(mode
,
217 text_to_cstring(name
));
219 rc
= uuid_destroy(ns_uuid
);
220 if (rc
!= UUID_RC_OK
)
228 uuid_generate_v3(PG_FUNCTION_ARGS
)
230 pg_uuid_t
*ns
= PG_GETARG_UUID_P(0);
231 text
*name
= PG_GETARG_TEXT_P(1);
233 return uuid_generate_v35_internal(UUID_MAKE_V3
, ns
, name
);
238 uuid_generate_v4(PG_FUNCTION_ARGS
)
240 return uuid_generate_internal(UUID_MAKE_V4
, NULL
, NULL
);
245 uuid_generate_v5(PG_FUNCTION_ARGS
)
247 pg_uuid_t
*ns
= PG_GETARG_UUID_P(0);
248 text
*name
= PG_GETARG_TEXT_P(1);
250 return uuid_generate_v35_internal(UUID_MAKE_V5
, ns
, name
);