Fix pg_dump bug in the database-level collation patch. "datcollate" and
[PostgreSQL.git] / contrib / uuid-ossp / uuid-ossp.c
blob093626b087952e81a47fc055ebc200c8b9040daf
1 /*-------------------------------------------------------------------------
3 * UUID generation functions using the OSSP UUID library
5 * Copyright (c) 2007-2008 PostgreSQL Global Development Group
7 * $PostgreSQL$
9 *-------------------------------------------------------------------------
12 #include "postgres.h"
13 #include "fmgr.h"
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>
25 #else
26 #ifdef HAVE_UUID_H
27 #include <uuid.h>
28 #else
29 #error OSSP uuid.h not found
30 #endif
31 #endif
33 /* better both be 16 */
34 #if (UUID_LEN != UUID_LEN_BIN)
35 #error UUID length mismatch
36 #endif
39 PG_MODULE_MAGIC;
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);
67 static void
68 pguuid_complain(uuid_rc_t rc)
70 char *err = uuid_error(rc);
72 if (err != NULL)
73 ereport(ERROR,
74 (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
75 errmsg("OSSP uuid library failure: %s", err)));
76 else
77 ereport(ERROR,
78 (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
79 errmsg("OSSP uuid library failure: error code %d", rc)));
82 static char *
83 uuid_to_string(const uuid_t * uuid)
85 char *buf = palloc(UUID_LEN_STR + 1);
86 void *ptr = buf;
87 size_t len = UUID_LEN_STR + 1;
88 uuid_rc_t rc;
90 rc = uuid_export(uuid, UUID_FMT_STR, &ptr, &len);
91 if (rc != UUID_RC_OK)
92 pguuid_complain(rc);
94 return buf;
98 static void
99 string_to_uuid(const char *str, uuid_t * uuid)
101 uuid_rc_t rc;
103 rc = uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR + 1);
104 if (rc != UUID_RC_OK)
105 pguuid_complain(rc);
109 static Datum
110 special_uuid_value(const char *name)
112 uuid_t *uuid;
113 char *str;
114 uuid_rc_t rc;
116 rc = uuid_create(&uuid);
117 if (rc != UUID_RC_OK)
118 pguuid_complain(rc);
119 rc = uuid_load(uuid, name);
120 if (rc != UUID_RC_OK)
121 pguuid_complain(rc);
122 str = uuid_to_string(uuid);
123 rc = uuid_destroy(uuid);
124 if (rc != UUID_RC_OK)
125 pguuid_complain(rc);
127 return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
131 Datum
132 uuid_nil(PG_FUNCTION_ARGS)
134 return special_uuid_value("nil");
138 Datum
139 uuid_ns_dns(PG_FUNCTION_ARGS)
141 return special_uuid_value("ns:DNS");
145 Datum
146 uuid_ns_url(PG_FUNCTION_ARGS)
148 return special_uuid_value("ns:URL");
152 Datum
153 uuid_ns_oid(PG_FUNCTION_ARGS)
155 return special_uuid_value("ns:OID");
159 Datum
160 uuid_ns_x500(PG_FUNCTION_ARGS)
162 return special_uuid_value("ns:X500");
166 static Datum
167 uuid_generate_internal(int mode, const uuid_t * ns, const char *name)
169 uuid_t *uuid;
170 char *str;
171 uuid_rc_t rc;
173 rc = uuid_create(&uuid);
174 if (rc != UUID_RC_OK)
175 pguuid_complain(rc);
176 rc = uuid_make(uuid, mode, ns, name);
177 if (rc != UUID_RC_OK)
178 pguuid_complain(rc);
179 str = uuid_to_string(uuid);
180 rc = uuid_destroy(uuid);
181 if (rc != UUID_RC_OK)
182 pguuid_complain(rc);
184 return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
188 Datum
189 uuid_generate_v1(PG_FUNCTION_ARGS)
191 return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL);
195 Datum
196 uuid_generate_v1mc(PG_FUNCTION_ARGS)
198 return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL);
202 static Datum
203 uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
205 uuid_t *ns_uuid;
206 Datum result;
207 uuid_rc_t rc;
209 rc = uuid_create(&ns_uuid);
210 if (rc != UUID_RC_OK)
211 pguuid_complain(rc);
212 string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
213 ns_uuid);
215 result = uuid_generate_internal(mode,
216 ns_uuid,
217 text_to_cstring(name));
219 rc = uuid_destroy(ns_uuid);
220 if (rc != UUID_RC_OK)
221 pguuid_complain(rc);
223 return result;
227 Datum
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);
237 Datum
238 uuid_generate_v4(PG_FUNCTION_ARGS)
240 return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL);
244 Datum
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);