Age Owner TLA Line data Source code
1 : /*
2 : * pgcrypto.c
3 : * Various cryptographic stuff for PostgreSQL.
4 : *
5 : * Copyright (c) 2001 Marko Kreen
6 : * All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : * 1. Redistributions of source code must retain the above copyright
12 : * notice, this list of conditions and the following disclaimer.
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 : * SUCH DAMAGE.
28 : *
29 : * contrib/pgcrypto/pgcrypto.c
30 : */
31 :
32 : #include "postgres.h"
33 :
34 : #include <ctype.h>
35 :
36 : #include "parser/scansup.h"
37 : #include "pgcrypto.h"
38 : #include "px-crypt.h"
39 : #include "px.h"
40 : #include "utils/builtins.h"
41 : #include "utils/uuid.h"
42 : #include "varatt.h"
43 :
6158 tgl 44 GIC 22 : PG_MODULE_MAGIC;
6158 tgl 45 ECB :
46 : /* private stuff */
47 :
48 : typedef int (*PFN) (const char *name, void **res);
49 : static void *find_provider(text *name, PFN provider_lookup, const char *desc,
50 : int silent);
51 :
52 : /* SQL function: hash(bytea, text) returns bytea */
7901 bruce 53 GIC 8 : PG_FUNCTION_INFO_V1(pg_digest);
54 :
8195 peter_e 55 ECB : Datum
7901 bruce 56 GIC 44 : pg_digest(PG_FUNCTION_ARGS)
57 : {
7901 bruce 58 ECB : bytea *arg;
59 : text *name;
60 : unsigned len,
61 : hlen;
62 : PX_MD *md;
63 : bytea *res;
64 :
2219 noah 65 GIC 44 : name = PG_GETARG_TEXT_PP(1);
66 :
7901 bruce 67 ECB : /* will give error if fails */
7901 bruce 68 GIC 44 : md = find_provider(name, (PFN) px_find_digest, "Digest", 0);
69 :
7901 bruce 70 CBC 43 : hlen = px_md_result_size(md);
71 :
8053 72 43 : res = (text *) palloc(hlen + VARHDRSZ);
5885 tgl 73 GIC 43 : SET_VARSIZE(res, hlen + VARHDRSZ);
8053 bruce 74 ECB :
2219 noah 75 CBC 43 : arg = PG_GETARG_BYTEA_PP(0);
2219 noah 76 GIC 43 : len = VARSIZE_ANY_EXHDR(arg);
8053 bruce 77 ECB :
2219 noah 78 CBC 43 : px_md_update(md, (uint8 *) VARDATA_ANY(arg), len);
6406 tgl 79 GIC 43 : px_md_finish(md, (uint8 *) VARDATA(res));
7901 bruce 80 CBC 43 : px_md_free(md);
8053 bruce 81 ECB :
8195 peter_e 82 CBC 43 : PG_FREE_IF_COPY(arg, 0);
8097 bruce 83 GIC 43 : PG_FREE_IF_COPY(name, 1);
8053 bruce 84 ECB :
7901 bruce 85 CBC 43 : PG_RETURN_BYTEA_P(res);
86 : }
8195 peter_e 87 ECB :
88 : /* SQL function: hmac(data:bytea, key:bytea, type:text) returns bytea */
7901 bruce 89 GIC 7 : PG_FUNCTION_INFO_V1(pg_hmac);
90 :
7901 bruce 91 ECB : Datum
7901 bruce 92 GIC 15 : pg_hmac(PG_FUNCTION_ARGS)
93 : {
7901 bruce 94 ECB : bytea *arg;
95 : bytea *key;
96 : text *name;
97 : unsigned len,
98 : hlen,
99 : klen;
100 : PX_HMAC *h;
101 : bytea *res;
102 :
2219 noah 103 GIC 15 : name = PG_GETARG_TEXT_PP(2);
104 :
7901 bruce 105 ECB : /* will give error if fails */
7901 bruce 106 GIC 15 : h = find_provider(name, (PFN) px_find_hmac, "HMAC", 0);
107 :
7901 bruce 108 CBC 14 : hlen = px_hmac_result_size(h);
109 :
110 14 : res = (text *) palloc(hlen + VARHDRSZ);
5885 tgl 111 GIC 14 : SET_VARSIZE(res, hlen + VARHDRSZ);
7901 bruce 112 ECB :
2219 noah 113 CBC 14 : arg = PG_GETARG_BYTEA_PP(0);
2219 noah 114 GIC 14 : key = PG_GETARG_BYTEA_PP(1);
2219 noah 115 CBC 14 : len = VARSIZE_ANY_EXHDR(arg);
116 14 : klen = VARSIZE_ANY_EXHDR(key);
7901 bruce 117 ECB :
2219 noah 118 CBC 14 : px_hmac_init(h, (uint8 *) VARDATA_ANY(key), klen);
2219 noah 119 GIC 14 : px_hmac_update(h, (uint8 *) VARDATA_ANY(arg), len);
6406 tgl 120 CBC 14 : px_hmac_finish(h, (uint8 *) VARDATA(res));
7901 bruce 121 14 : px_hmac_free(h);
7901 bruce 122 ECB :
7901 bruce 123 CBC 14 : PG_FREE_IF_COPY(arg, 0);
7901 bruce 124 GIC 14 : PG_FREE_IF_COPY(key, 1);
7901 bruce 125 CBC 14 : PG_FREE_IF_COPY(name, 2);
7901 bruce 126 ECB :
7901 bruce 127 CBC 14 : PG_RETURN_BYTEA_P(res);
128 : }
7901 bruce 129 ECB :
130 :
131 : /* SQL function: pg_gen_salt(text) returns text */
7901 bruce 132 GIC 4 : PG_FUNCTION_INFO_V1(pg_gen_salt);
133 :
7901 bruce 134 ECB : Datum
7901 bruce 135 GIC 3 : pg_gen_salt(PG_FUNCTION_ARGS)
136 : {
5493 tgl 137 CBC 3 : text *arg0 = PG_GETARG_TEXT_PP(0);
138 : int len;
7901 bruce 139 ECB : char buf[PX_MAX_SALT_LEN + 1];
140 :
5493 tgl 141 GIC 3 : text_to_cstring_buffer(arg0, buf, sizeof(buf));
7868 bruce 142 3 : len = px_gen_salt(buf, buf, 0);
6593 neilc 143 CBC 3 : if (len < 0)
7199 tgl 144 1 : ereport(ERROR,
7199 tgl 145 ECB : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6593 neilc 146 : errmsg("gen_salt: %s", px_strerror(len))));
147 :
7901 bruce 148 GIC 2 : PG_FREE_IF_COPY(arg0, 0);
149 :
5493 tgl 150 CBC 2 : PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
151 : }
7868 bruce 152 ECB :
153 : /* SQL function: pg_gen_salt(text, int4) returns text */
7868 bruce 154 GIC 3 : PG_FUNCTION_INFO_V1(pg_gen_salt_rounds);
155 :
7868 bruce 156 ECB : Datum
7868 bruce 157 GIC 2 : pg_gen_salt_rounds(PG_FUNCTION_ARGS)
158 : {
5493 tgl 159 CBC 2 : text *arg0 = PG_GETARG_TEXT_PP(0);
5493 tgl 160 GIC 2 : int rounds = PG_GETARG_INT32(1);
6593 neilc 161 ECB : int len;
7868 bruce 162 : char buf[PX_MAX_SALT_LEN + 1];
163 :
5493 tgl 164 GIC 2 : text_to_cstring_buffer(arg0, buf, sizeof(buf));
7868 bruce 165 2 : len = px_gen_salt(buf, buf, rounds);
6593 neilc 166 CBC 2 : if (len < 0)
7199 tgl 167 LBC 0 : ereport(ERROR,
7199 tgl 168 ECB : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6385 bruce 169 EUB : errmsg("gen_salt: %s", px_strerror(len))));
170 :
7868 bruce 171 GIC 2 : PG_FREE_IF_COPY(arg0, 0);
172 :
5493 tgl 173 CBC 2 : PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len));
174 : }
7901 bruce 175 ECB :
176 : /* SQL function: pg_crypt(psw:text, salt:text) returns text */
7901 bruce 177 GIC 5 : PG_FUNCTION_INFO_V1(pg_crypt);
178 :
7901 bruce 179 ECB : Datum
7901 bruce 180 GIC 25 : pg_crypt(PG_FUNCTION_ARGS)
181 : {
5493 tgl 182 CBC 25 : text *arg0 = PG_GETARG_TEXT_PP(0);
5493 tgl 183 GIC 25 : text *arg1 = PG_GETARG_TEXT_PP(1);
7901 bruce 184 ECB : char *buf0,
185 : *buf1,
186 : *cres,
187 : *resbuf;
188 : text *res;
189 :
5493 tgl 190 GIC 25 : buf0 = text_to_cstring(arg0);
191 25 : buf1 = text_to_cstring(arg1);
7901 bruce 192 ECB :
5994 neilc 193 CBC 25 : resbuf = palloc0(PX_MAX_CRYPT);
194 :
7901 bruce 195 25 : cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT);
196 :
197 20 : pfree(buf0);
7901 bruce 198 GIC 20 : pfree(buf1);
7901 bruce 199 ECB :
7901 bruce 200 CBC 20 : if (cres == NULL)
7199 tgl 201 GIC 2 : ereport(ERROR,
7199 tgl 202 ECB : (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
203 : errmsg("crypt(3) returned NULL")));
204 :
5493 tgl 205 GIC 18 : res = cstring_to_text(cres);
206 :
7901 bruce 207 CBC 18 : pfree(resbuf);
208 :
209 18 : PG_FREE_IF_COPY(arg0, 0);
7901 bruce 210 GIC 18 : PG_FREE_IF_COPY(arg1, 1);
7901 bruce 211 ECB :
7901 bruce 212 CBC 18 : PG_RETURN_TEXT_P(res);
213 : }
7901 bruce 214 ECB :
215 : /* SQL function: pg_encrypt(bytea, bytea, text) returns bytea */
7901 bruce 216 GIC 7 : PG_FUNCTION_INFO_V1(pg_encrypt);
217 :
7901 bruce 218 ECB : Datum
7901 bruce 219 GIC 55 : pg_encrypt(PG_FUNCTION_ARGS)
220 : {
7836 bruce 221 ECB : int err;
222 : bytea *data,
223 : *key,
224 : *res;
225 : text *type;
226 : PX_Combo *c;
227 : unsigned dlen,
228 : klen,
229 : rlen;
230 :
2219 noah 231 GIC 55 : type = PG_GETARG_TEXT_PP(2);
7836 bruce 232 55 : c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
7901 bruce 233 ECB :
2219 noah 234 CBC 54 : data = PG_GETARG_BYTEA_PP(0);
2219 noah 235 GIC 54 : key = PG_GETARG_BYTEA_PP(1);
2219 noah 236 CBC 54 : dlen = VARSIZE_ANY_EXHDR(data);
237 54 : klen = VARSIZE_ANY_EXHDR(key);
7901 bruce 238 ECB :
7901 bruce 239 CBC 54 : rlen = px_combo_encrypt_len(c, dlen);
7901 bruce 240 GIC 54 : res = palloc(VARHDRSZ + rlen);
7901 bruce 241 ECB :
2219 noah 242 CBC 54 : err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen, NULL, 0);
7901 bruce 243 GIC 54 : if (!err)
2219 noah 244 CBC 50 : err = px_combo_encrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
6406 tgl 245 ECB : (uint8 *) VARDATA(res), &rlen);
7901 bruce 246 CBC 54 : px_combo_free(c);
247 :
248 54 : PG_FREE_IF_COPY(data, 0);
7901 bruce 249 GIC 54 : PG_FREE_IF_COPY(key, 1);
7901 bruce 250 CBC 54 : PG_FREE_IF_COPY(type, 2);
7836 bruce 251 ECB :
7836 bruce 252 CBC 54 : if (err)
253 : {
7901 254 33 : pfree(res);
7199 tgl 255 GIC 33 : ereport(ERROR,
7199 tgl 256 ECB : (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
6593 neilc 257 : errmsg("encrypt error: %s", px_strerror(err))));
258 : }
259 :
5885 tgl 260 GIC 21 : SET_VARSIZE(res, VARHDRSZ + rlen);
7901 bruce 261 21 : PG_RETURN_BYTEA_P(res);
7901 bruce 262 ECB : }
263 :
264 : /* SQL function: pg_decrypt(bytea, bytea, text) returns bytea */
7901 bruce 265 GIC 3 : PG_FUNCTION_INFO_V1(pg_decrypt);
266 :
7901 bruce 267 ECB : Datum
7901 bruce 268 GIC 5 : pg_decrypt(PG_FUNCTION_ARGS)
269 : {
7836 bruce 270 ECB : int err;
271 : bytea *data,
272 : *key,
273 : *res;
274 : text *type;
275 : PX_Combo *c;
276 : unsigned dlen,
277 : klen,
278 : rlen;
279 :
2219 noah 280 GIC 5 : type = PG_GETARG_TEXT_PP(2);
7836 bruce 281 5 : c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
7901 bruce 282 ECB :
2219 noah 283 CBC 5 : data = PG_GETARG_BYTEA_PP(0);
2219 noah 284 GIC 5 : key = PG_GETARG_BYTEA_PP(1);
2219 noah 285 CBC 5 : dlen = VARSIZE_ANY_EXHDR(data);
286 5 : klen = VARSIZE_ANY_EXHDR(key);
7901 bruce 287 ECB :
7901 bruce 288 CBC 5 : rlen = px_combo_decrypt_len(c, dlen);
7901 bruce 289 GIC 5 : res = palloc(VARHDRSZ + rlen);
7901 bruce 290 ECB :
2219 noah 291 CBC 5 : err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen, NULL, 0);
7901 bruce 292 GIC 5 : if (!err)
2219 noah 293 CBC 5 : err = px_combo_decrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
6406 tgl 294 ECB : (uint8 *) VARDATA(res), &rlen);
7901 bruce 295 :
7901 bruce 296 GIC 5 : px_combo_free(c);
297 :
7901 bruce 298 CBC 5 : if (err)
7199 tgl 299 GIC 1 : ereport(ERROR,
7199 tgl 300 ECB : (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
6593 neilc 301 : errmsg("decrypt error: %s", px_strerror(err))));
302 :
5885 tgl 303 GIC 4 : SET_VARSIZE(res, VARHDRSZ + rlen);
304 :
7901 bruce 305 CBC 4 : PG_FREE_IF_COPY(data, 0);
7901 bruce 306 GIC 4 : PG_FREE_IF_COPY(key, 1);
7901 bruce 307 CBC 4 : PG_FREE_IF_COPY(type, 2);
7901 bruce 308 ECB :
7901 bruce 309 CBC 4 : PG_RETURN_BYTEA_P(res);
310 : }
7901 bruce 311 ECB :
312 : /* SQL function: pg_encrypt_iv(bytea, bytea, bytea, text) returns bytea */
7901 bruce 313 GIC 6 : PG_FUNCTION_INFO_V1(pg_encrypt_iv);
314 :
7901 bruce 315 ECB : Datum
7901 bruce 316 GIC 5 : pg_encrypt_iv(PG_FUNCTION_ARGS)
317 : {
7836 bruce 318 ECB : int err;
319 : bytea *data,
320 : *key,
321 : *iv,
322 : *res;
323 : text *type;
324 : PX_Combo *c;
325 : unsigned dlen,
326 : klen,
327 : ivlen,
328 : rlen;
329 :
2219 noah 330 GIC 5 : type = PG_GETARG_TEXT_PP(3);
7836 bruce 331 5 : c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
7901 bruce 332 ECB :
2219 noah 333 CBC 5 : data = PG_GETARG_BYTEA_PP(0);
2219 noah 334 GIC 5 : key = PG_GETARG_BYTEA_PP(1);
2219 noah 335 CBC 5 : iv = PG_GETARG_BYTEA_PP(2);
336 5 : dlen = VARSIZE_ANY_EXHDR(data);
337 5 : klen = VARSIZE_ANY_EXHDR(key);
338 5 : ivlen = VARSIZE_ANY_EXHDR(iv);
7901 bruce 339 ECB :
7901 bruce 340 CBC 5 : rlen = px_combo_encrypt_len(c, dlen);
7901 bruce 341 GIC 5 : res = palloc(VARHDRSZ + rlen);
7901 bruce 342 ECB :
2219 noah 343 CBC 5 : err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen,
344 : (uint8 *) VARDATA_ANY(iv), ivlen);
7901 bruce 345 5 : if (!err)
2219 noah 346 GIC 5 : err = px_combo_encrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
4090 tgl 347 ECB : (uint8 *) VARDATA(res), &rlen);
7901 bruce 348 :
7901 bruce 349 GIC 5 : px_combo_free(c);
350 :
7901 bruce 351 CBC 5 : if (err)
7199 tgl 352 GIC 3 : ereport(ERROR,
7199 tgl 353 ECB : (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
6593 neilc 354 : errmsg("encrypt_iv error: %s", px_strerror(err))));
355 :
5885 tgl 356 GIC 2 : SET_VARSIZE(res, VARHDRSZ + rlen);
357 :
7901 bruce 358 CBC 2 : PG_FREE_IF_COPY(data, 0);
7901 bruce 359 GIC 2 : PG_FREE_IF_COPY(key, 1);
7901 bruce 360 CBC 2 : PG_FREE_IF_COPY(iv, 2);
361 2 : PG_FREE_IF_COPY(type, 3);
7901 bruce 362 ECB :
7901 bruce 363 CBC 2 : PG_RETURN_BYTEA_P(res);
364 : }
7901 bruce 365 ECB :
366 : /* SQL function: pg_decrypt_iv(bytea, bytea, bytea, text) returns bytea */
7901 bruce 367 GIC 6 : PG_FUNCTION_INFO_V1(pg_decrypt_iv);
368 :
7901 bruce 369 ECB : Datum
7901 bruce 370 GIC 6 : pg_decrypt_iv(PG_FUNCTION_ARGS)
371 : {
7836 bruce 372 ECB : int err;
373 : bytea *data,
374 : *key,
375 : *iv,
376 : *res;
377 : text *type;
378 : PX_Combo *c;
379 : unsigned dlen,
380 : klen,
381 : rlen,
382 : ivlen;
383 :
2219 noah 384 GIC 6 : type = PG_GETARG_TEXT_PP(3);
7836 bruce 385 6 : c = find_provider(type, (PFN) px_find_combo, "Cipher", 0);
7901 bruce 386 ECB :
2219 noah 387 CBC 6 : data = PG_GETARG_BYTEA_PP(0);
2219 noah 388 GIC 6 : key = PG_GETARG_BYTEA_PP(1);
2219 noah 389 CBC 6 : iv = PG_GETARG_BYTEA_PP(2);
390 6 : dlen = VARSIZE_ANY_EXHDR(data);
391 6 : klen = VARSIZE_ANY_EXHDR(key);
392 6 : ivlen = VARSIZE_ANY_EXHDR(iv);
7901 bruce 393 ECB :
7901 bruce 394 CBC 6 : rlen = px_combo_decrypt_len(c, dlen);
7901 bruce 395 GIC 6 : res = palloc(VARHDRSZ + rlen);
7901 bruce 396 ECB :
2219 noah 397 CBC 6 : err = px_combo_init(c, (uint8 *) VARDATA_ANY(key), klen,
398 : (uint8 *) VARDATA_ANY(iv), ivlen);
7901 bruce 399 6 : if (!err)
2219 noah 400 GIC 6 : err = px_combo_decrypt(c, (uint8 *) VARDATA_ANY(data), dlen,
4090 tgl 401 ECB : (uint8 *) VARDATA(res), &rlen);
7901 bruce 402 :
7901 bruce 403 GIC 6 : px_combo_free(c);
404 :
7901 bruce 405 CBC 6 : if (err)
7199 tgl 406 GIC 4 : ereport(ERROR,
7199 tgl 407 ECB : (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
6593 neilc 408 : errmsg("decrypt_iv error: %s", px_strerror(err))));
409 :
5885 tgl 410 GIC 2 : SET_VARSIZE(res, VARHDRSZ + rlen);
411 :
7901 bruce 412 CBC 2 : PG_FREE_IF_COPY(data, 0);
7901 bruce 413 GIC 2 : PG_FREE_IF_COPY(key, 1);
7901 bruce 414 CBC 2 : PG_FREE_IF_COPY(iv, 2);
415 2 : PG_FREE_IF_COPY(type, 3);
7901 bruce 416 ECB :
7901 bruce 417 CBC 2 : PG_RETURN_BYTEA_P(res);
418 : }
7901 bruce 419 ECB :
420 : /* SQL function: pg_random_bytes(int4) returns bytea */
6114 neilc 421 GIC 1 : PG_FUNCTION_INFO_V1(pg_random_bytes);
422 :
6114 neilc 423 ECB : Datum
6114 neilc 424 UIC 0 : pg_random_bytes(PG_FUNCTION_ARGS)
425 : {
6031 bruce 426 UBC 0 : int len = PG_GETARG_INT32(0);
427 : bytea *res;
6114 neilc 428 EUB :
6114 neilc 429 UIC 0 : if (len < 1 || len > 1024)
430 0 : ereport(ERROR,
6114 neilc 431 EUB : (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
432 : errmsg("Length not in range")));
433 :
6114 neilc 434 UIC 0 : res = palloc(VARHDRSZ + len);
5885 tgl 435 0 : SET_VARSIZE(res, VARHDRSZ + len);
6114 neilc 436 EUB :
437 : /* generate result */
2316 heikki.linnakangas 438 UIC 0 : if (!pg_strong_random(VARDATA(res), len))
439 0 : px_THROW_ERROR(PXE_NO_RANDOM);
6114 neilc 440 EUB :
6114 neilc 441 UBC 0 : PG_RETURN_BYTEA_P(res);
442 : }
6114 neilc 443 EUB :
444 : /* SQL function: gen_random_uuid() returns uuid */
3369 tgl 445 GIC 1 : PG_FUNCTION_INFO_V1(pg_random_uuid);
446 :
3369 tgl 447 ECB : Datum
3369 tgl 448 UIC 0 : pg_random_uuid(PG_FUNCTION_ARGS)
449 : {
1365 peter 450 EUB : /* redirect to built-in function */
1365 peter 451 UIC 0 : return gen_random_uuid(fcinfo);
452 : }
3369 tgl 453 EUB :
454 : static void *
7836 bruce 455 GIC 130 : find_provider(text *name,
456 : PFN provider_lookup,
1986 peter_e 457 ECB : const char *desc, int silent)
458 : {
459 : void *res;
460 : char *buf;
461 : int err;
462 :
2219 noah 463 GIC 130 : buf = downcase_truncate_identifier(VARDATA_ANY(name),
464 130 : VARSIZE_ANY_EXHDR(name),
6911 tgl 465 ECB : false);
8053 bruce 466 :
7901 bruce 467 GIC 130 : err = provider_lookup(buf, &res);
468 :
7901 bruce 469 CBC 130 : if (err && !silent)
7199 tgl 470 GIC 3 : ereport(ERROR,
7199 tgl 471 ECB : (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6593 neilc 472 : errmsg("Cannot use \"%s\": %s", buf, px_strerror(err))));
473 :
6911 tgl 474 GIC 127 : pfree(buf);
475 :
7901 bruce 476 CBC 127 : return err ? NULL : res;
477 : }
|