PostgreSQL Source Code git master
uuid.c File Reference
#include "postgres.h"
#include <time.h>
#include "common/hashfn.h"
#include "lib/hyperloglog.h"
#include "libpq/pqformat.h"
#include "port/pg_bswap.h"
#include "utils/fmgrprotos.h"
#include "utils/guc.h"
#include "utils/sortsupport.h"
#include "utils/timestamp.h"
#include "utils/uuid.h"
Include dependency graph for uuid.c:

Go to the source code of this file.

Data Structures

struct  uuid_sortsupport_state
 

Macros

#define NS_PER_S   INT64CONST(1000000000)
 
#define NS_PER_MS   INT64CONST(1000000)
 
#define NS_PER_US   INT64CONST(1000)
 
#define SUBMS_MINIMAL_STEP_BITS   12
 
#define SUBMS_BITS   12
 
#define SUBMS_MINIMAL_STEP_NS   ((NS_PER_MS / (1 << SUBMS_MINIMAL_STEP_BITS)) + 1)
 
#define GREGORIAN_EPOCH_JDATE   INT64CONST(2299161)
 

Functions

static void string_to_uuid (const char *source, pg_uuid_t *uuid, Node *escontext)
 
static int uuid_internal_cmp (const pg_uuid_t *arg1, const pg_uuid_t *arg2)
 
static int uuid_fast_cmp (Datum x, Datum y, SortSupport ssup)
 
static bool uuid_abbrev_abort (int memtupcount, SortSupport ssup)
 
static Datum uuid_abbrev_convert (Datum original, SortSupport ssup)
 
static void uuid_set_version (pg_uuid_t *uuid, unsigned char version)
 
static int64 get_real_time_ns_ascending ()
 
Datum uuid_in (PG_FUNCTION_ARGS)
 
Datum uuid_out (PG_FUNCTION_ARGS)
 
Datum uuid_recv (PG_FUNCTION_ARGS)
 
Datum uuid_send (PG_FUNCTION_ARGS)
 
Datum uuid_lt (PG_FUNCTION_ARGS)
 
Datum uuid_le (PG_FUNCTION_ARGS)
 
Datum uuid_eq (PG_FUNCTION_ARGS)
 
Datum uuid_ge (PG_FUNCTION_ARGS)
 
Datum uuid_gt (PG_FUNCTION_ARGS)
 
Datum uuid_ne (PG_FUNCTION_ARGS)
 
Datum uuid_cmp (PG_FUNCTION_ARGS)
 
Datum uuid_sortsupport (PG_FUNCTION_ARGS)
 
Datum uuid_hash (PG_FUNCTION_ARGS)
 
Datum uuid_hash_extended (PG_FUNCTION_ARGS)
 
Datum gen_random_uuid (PG_FUNCTION_ARGS)
 
static pg_uuid_tgenerate_uuidv7 (int64 ns)
 
Datum uuidv7 (PG_FUNCTION_ARGS)
 
Datum uuidv7_interval (PG_FUNCTION_ARGS)
 
Datum uuid_extract_timestamp (PG_FUNCTION_ARGS)
 
Datum uuid_extract_version (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ GREGORIAN_EPOCH_JDATE

#define GREGORIAN_EPOCH_JDATE   INT64CONST(2299161)

Definition at line 637 of file uuid.c.

◆ NS_PER_MS

#define NS_PER_MS   INT64CONST(1000000)

Definition at line 30 of file uuid.c.

◆ NS_PER_S

#define NS_PER_S   INT64CONST(1000000000)

Definition at line 29 of file uuid.c.

◆ NS_PER_US

#define NS_PER_US   INT64CONST(1000)

Definition at line 31 of file uuid.c.

◆ SUBMS_BITS

#define SUBMS_BITS   12

Definition at line 53 of file uuid.c.

◆ SUBMS_MINIMAL_STEP_BITS

#define SUBMS_MINIMAL_STEP_BITS   12

Definition at line 51 of file uuid.c.

◆ SUBMS_MINIMAL_STEP_NS

#define SUBMS_MINIMAL_STEP_NS   ((NS_PER_MS / (1 << SUBMS_MINIMAL_STEP_BITS)) + 1)

Definition at line 54 of file uuid.c.

Function Documentation

◆ gen_random_uuid()

Datum gen_random_uuid ( PG_FUNCTION_ARGS  )

Definition at line 456 of file uuid.c.

457{
458 pg_uuid_t *uuid = palloc(UUID_LEN);
459
460 if (!pg_strong_random(uuid, UUID_LEN))
462 (errcode(ERRCODE_INTERNAL_ERROR),
463 errmsg("could not generate random values")));
464
465 /*
466 * Set magic numbers for a "version 4" (pseudorandom) UUID and variant,
467 * see https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
468 */
469 uuid_set_version(uuid, 4);
470
471 PG_RETURN_UUID_P(uuid);
472}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void * palloc(Size size)
Definition: mcxt.c:1317
bool pg_strong_random(void *buf, size_t len)
Definition: uuid.h:21
static void uuid_set_version(pg_uuid_t *uuid, unsigned char version)
Definition: uuid.c:440
#define PG_RETURN_UUID_P(X)
Definition: uuid.h:32
#define UUID_LEN
Definition: uuid.h:18

References ereport, errcode(), errmsg(), ERROR, palloc(), PG_RETURN_UUID_P, pg_strong_random(), UUID_LEN, and uuid_set_version().

Referenced by pg_random_uuid().

◆ generate_uuidv7()

static pg_uuid_t * generate_uuidv7 ( int64  ns)
static

Definition at line 530 of file uuid.c.

531{
532 pg_uuid_t *uuid = palloc(UUID_LEN);
533 int64 unix_ts_ms;
534 int32 increased_clock_precision;
535
536 unix_ts_ms = ns / NS_PER_MS;
537
538 /* Fill in time part */
539 uuid->data[0] = (unsigned char) (unix_ts_ms >> 40);
540 uuid->data[1] = (unsigned char) (unix_ts_ms >> 32);
541 uuid->data[2] = (unsigned char) (unix_ts_ms >> 24);
542 uuid->data[3] = (unsigned char) (unix_ts_ms >> 16);
543 uuid->data[4] = (unsigned char) (unix_ts_ms >> 8);
544 uuid->data[5] = (unsigned char) unix_ts_ms;
545
546 /*
547 * sub-millisecond timestamp fraction (SUBMS_BITS bits, not
548 * SUBMS_MINIMAL_STEP_BITS)
549 */
550 increased_clock_precision = ((ns % NS_PER_MS) * (1 << SUBMS_BITS)) / NS_PER_MS;
551
552 /* Fill the increased clock precision to "rand_a" bits */
553 uuid->data[6] = (unsigned char) (increased_clock_precision >> 8);
554 uuid->data[7] = (unsigned char) (increased_clock_precision);
555
556 /* fill everything after the increased clock precision with random bytes */
557 if (!pg_strong_random(&uuid->data[8], UUID_LEN - 8))
559 (errcode(ERRCODE_INTERNAL_ERROR),
560 errmsg("could not generate random values")));
561
562#if SUBMS_MINIMAL_STEP_BITS == 10
563
564 /*
565 * On systems that have only 10 bits of sub-ms precision, 2 least
566 * significant are dependent on other time-specific bits, and they do not
567 * contribute to uniqueness. To make these bit random we mix in two bits
568 * from CSPRNG. SUBMS_MINIMAL_STEP is chosen so that we still guarantee
569 * monotonicity despite altering these bits.
570 */
571 uuid->data[7] = uuid->data[7] ^ (uuid->data[8] >> 6);
572#endif
573
574 /*
575 * Set magic numbers for a "version 7" (pseudorandom) UUID and variant,
576 * see https://www.rfc-editor.org/rfc/rfc9562#name-version-field
577 */
578 uuid_set_version(uuid, 7);
579
580 return uuid;
581}
int64_t int64
Definition: c.h:485
int32_t int32
Definition: c.h:484
unsigned char data[UUID_LEN]
Definition: uuid.h:22
#define SUBMS_BITS
Definition: uuid.c:53
#define NS_PER_MS
Definition: uuid.c:30

References pg_uuid_t::data, ereport, errcode(), errmsg(), ERROR, NS_PER_MS, palloc(), pg_strong_random(), SUBMS_BITS, UUID_LEN, and uuid_set_version().

Referenced by uuidv7(), and uuidv7_interval().

◆ get_real_time_ns_ascending()

static int64 get_real_time_ns_ascending ( )
inlinestatic

Definition at line 480 of file uuid.c.

481{
482 static int64 previous_ns = 0;
483 int64 ns;
484
485 /* Get the current real timestamp */
486
487#ifdef _MSC_VER
488 struct timeval tmp;
489
490 gettimeofday(&tmp, NULL);
491 ns = tmp.tv_sec * NS_PER_S + tmp.tv_usec * NS_PER_US;
492#else
493 struct timespec tmp;
494
495 /*
496 * We don't use gettimeofday(), instead use clock_gettime() with
497 * CLOCK_REALTIME where available in order to get a high-precision
498 * (nanoseconds) real timestamp.
499 *
500 * Note while a timestamp returned by clock_gettime() with CLOCK_REALTIME
501 * is nanosecond-precision on most Unix-like platforms, on some platforms
502 * such as macOS it's restricted to microsecond-precision.
503 */
504 clock_gettime(CLOCK_REALTIME, &tmp);
505 ns = tmp.tv_sec * NS_PER_S + tmp.tv_nsec;
506#endif
507
508 /* Guarantee the minimal step advancement of the timestamp */
509 if (previous_ns + SUBMS_MINIMAL_STEP_NS >= ns)
510 ns = previous_ns + SUBMS_MINIMAL_STEP_NS;
511 previous_ns = ns;
512
513 return ns;
514}
#define SUBMS_MINIMAL_STEP_NS
Definition: uuid.c:54
#define NS_PER_S
Definition: uuid.c:29
#define NS_PER_US
Definition: uuid.c:31
int gettimeofday(struct timeval *tp, void *tzp)

References gettimeofday(), NS_PER_S, NS_PER_US, and SUBMS_MINIMAL_STEP_NS.

Referenced by uuidv7(), and uuidv7_interval().

◆ string_to_uuid()

static void string_to_uuid ( const char *  source,
pg_uuid_t uuid,
Node escontext 
)
static

Definition at line 127 of file uuid.c.

128{
129 const char *src = source;
130 bool braces = false;
131 int i;
132
133 if (src[0] == '{')
134 {
135 src++;
136 braces = true;
137 }
138
139 for (i = 0; i < UUID_LEN; i++)
140 {
141 char str_buf[3];
142
143 if (src[0] == '\0' || src[1] == '\0')
144 goto syntax_error;
145 memcpy(str_buf, src, 2);
146 if (!isxdigit((unsigned char) str_buf[0]) ||
147 !isxdigit((unsigned char) str_buf[1]))
148 goto syntax_error;
149
150 str_buf[2] = '\0';
151 uuid->data[i] = (unsigned char) strtoul(str_buf, NULL, 16);
152 src += 2;
153 if (src[0] == '-' && (i % 2) == 1 && i < UUID_LEN - 1)
154 src++;
155 }
156
157 if (braces)
158 {
159 if (*src != '}')
160 goto syntax_error;
161 src++;
162 }
163
164 if (*src != '\0')
165 goto syntax_error;
166
167 return;
168
170 ereturn(escontext,,
171 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
172 errmsg("invalid input syntax for type %s: \"%s\"",
173 "uuid", source)));
174}
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
int i
Definition: isn.c:72
static rewind_source * source
Definition: pg_rewind.c:89
void syntax_error(const char *source, int lineno, const char *line, const char *command, const char *msg, const char *more, int column)
Definition: pgbench.c:5491

References pg_uuid_t::data, ereturn, errcode(), errmsg(), i, source, syntax_error(), and UUID_LEN.

Referenced by uuid_in().

◆ uuid_abbrev_abort()

static bool uuid_abbrev_abort ( int  memtupcount,
SortSupport  ssup 
)
static

Definition at line 324 of file uuid.c.

325{
327 double abbr_card;
328
329 if (memtupcount < 10000 || uss->input_count < 10000 || !uss->estimating)
330 return false;
331
332 abbr_card = estimateHyperLogLog(&uss->abbr_card);
333
334 /*
335 * If we have >100k distinct values, then even if we were sorting many
336 * billion rows we'd likely still break even, and the penalty of undoing
337 * that many rows of abbrevs would probably not be worth it. Stop even
338 * counting at that point.
339 */
340 if (abbr_card > 100000.0)
341 {
342 if (trace_sort)
343 elog(LOG,
344 "uuid_abbrev: estimation ends at cardinality %f"
345 " after " INT64_FORMAT " values (%d rows)",
346 abbr_card, uss->input_count, memtupcount);
347 uss->estimating = false;
348 return false;
349 }
350
351 /*
352 * Target minimum cardinality is 1 per ~2k of non-null inputs. 0.5 row
353 * fudge factor allows us to abort earlier on genuinely pathological data
354 * where we've had exactly one abbreviated value in the first 2k
355 * (non-null) rows.
356 */
357 if (abbr_card < uss->input_count / 2000.0 + 0.5)
358 {
359 if (trace_sort)
360 elog(LOG,
361 "uuid_abbrev: aborting abbreviation at cardinality %f"
362 " below threshold %f after " INT64_FORMAT " values (%d rows)",
363 abbr_card, uss->input_count / 2000.0 + 0.5, uss->input_count,
364 memtupcount);
365 return true;
366 }
367
368 if (trace_sort)
369 elog(LOG,
370 "uuid_abbrev: cardinality %f after " INT64_FORMAT
371 " values (%d rows)", abbr_card, uss->input_count, memtupcount);
372
373 return false;
374}
#define INT64_FORMAT
Definition: c.h:506
#define LOG
Definition: elog.h:31
#define elog(elevel,...)
Definition: elog.h:225
double estimateHyperLogLog(hyperLogLogState *cState)
Definition: hyperloglog.c:186
void * ssup_extra
Definition: sortsupport.h:87
hyperLogLogState abbr_card
Definition: uuid.c:62
bool trace_sort
Definition: tuplesort.c:124

References uuid_sortsupport_state::abbr_card, elog, estimateHyperLogLog(), uuid_sortsupport_state::estimating, uuid_sortsupport_state::input_count, INT64_FORMAT, LOG, SortSupportData::ssup_extra, and trace_sort.

Referenced by uuid_sortsupport().

◆ uuid_abbrev_convert()

static Datum uuid_abbrev_convert ( Datum  original,
SortSupport  ssup 
)
static

Definition at line 384 of file uuid.c.

385{
387 pg_uuid_t *authoritative = DatumGetUUIDP(original);
388 Datum res;
389
390 memcpy(&res, authoritative->data, sizeof(Datum));
391 uss->input_count += 1;
392
393 if (uss->estimating)
394 {
395 uint32 tmp;
396
397#if SIZEOF_DATUM == 8
398 tmp = (uint32) res ^ (uint32) ((uint64) res >> 32);
399#else /* SIZEOF_DATUM != 8 */
400 tmp = (uint32) res;
401#endif
402
404 }
405
406 /*
407 * Byteswap on little-endian machines.
408 *
409 * This is needed so that ssup_datum_unsigned_cmp() (an unsigned integer
410 * 3-way comparator) works correctly on all platforms. If we didn't do
411 * this, the comparator would have to call memcmp() with a pair of
412 * pointers to the first byte of each abbreviated key, which is slower.
413 */
414 res = DatumBigEndianToNative(res);
415
416 return res;
417}
uint64_t uint64
Definition: c.h:489
uint32_t uint32
Definition: c.h:488
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
Definition: hyperloglog.c:167
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:227
uintptr_t Datum
Definition: postgres.h:69
static pg_uuid_t * DatumGetUUIDP(Datum X)
Definition: uuid.h:35

References uuid_sortsupport_state::abbr_card, addHyperLogLog(), pg_uuid_t::data, DatumGetUInt32(), DatumGetUUIDP(), uuid_sortsupport_state::estimating, hash_uint32(), uuid_sortsupport_state::input_count, res, and SortSupportData::ssup_extra.

Referenced by uuid_sortsupport().

◆ uuid_cmp()

Datum uuid_cmp ( PG_FUNCTION_ARGS  )

Definition at line 261 of file uuid.c.

262{
263 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
264 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
265
267}
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
static int uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2)
Definition: uuid.c:200
#define PG_GETARG_UUID_P(X)
Definition: uuid.h:40

References PG_GETARG_UUID_P, PG_RETURN_INT32, and uuid_internal_cmp().

◆ uuid_eq()

Datum uuid_eq ( PG_FUNCTION_ARGS  )

Definition at line 224 of file uuid.c.

225{
226 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
227 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
228
229 PG_RETURN_BOOL(uuid_internal_cmp(arg1, arg2) == 0);
230}
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

References PG_GETARG_UUID_P, PG_RETURN_BOOL, and uuid_internal_cmp().

◆ uuid_extract_timestamp()

Datum uuid_extract_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 645 of file uuid.c.

646{
647 pg_uuid_t *uuid = PG_GETARG_UUID_P(0);
648 int version;
649 uint64 tms;
650 TimestampTz ts;
651
652 /* check if RFC 9562 variant */
653 if ((uuid->data[8] & 0xc0) != 0x80)
655
656 version = uuid->data[6] >> 4;
657
658 if (version == 1)
659 {
660 tms = ((uint64) uuid->data[0] << 24)
661 + ((uint64) uuid->data[1] << 16)
662 + ((uint64) uuid->data[2] << 8)
663 + ((uint64) uuid->data[3])
664 + ((uint64) uuid->data[4] << 40)
665 + ((uint64) uuid->data[5] << 32)
666 + (((uint64) uuid->data[6] & 0xf) << 56)
667 + ((uint64) uuid->data[7] << 48);
668
669 /* convert 100-ns intervals to us, then adjust */
670 ts = (TimestampTz) (tms / 10) -
673 }
674
675 if (version == 7)
676 {
677 tms = (uuid->data[5])
678 + (((uint64) uuid->data[4]) << 8)
679 + (((uint64) uuid->data[3]) << 16)
680 + (((uint64) uuid->data[2]) << 24)
681 + (((uint64) uuid->data[1]) << 32)
682 + (((uint64) uuid->data[0]) << 40);
683
684 /* convert ms to us, then adjust */
685 ts = (TimestampTz) (tms * NS_PER_US) -
687
689 }
690
691 /* not a timestamp-containing UUID version */
693}
int64 TimestampTz
Definition: timestamp.h:39
#define USECS_PER_SEC
Definition: timestamp.h:134
#define UNIX_EPOCH_JDATE
Definition: timestamp.h:234
#define SECS_PER_DAY
Definition: timestamp.h:126
#define POSTGRES_EPOCH_JDATE
Definition: timestamp.h:235
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68
#define GREGORIAN_EPOCH_JDATE
Definition: uuid.c:637

References pg_uuid_t::data, GREGORIAN_EPOCH_JDATE, NS_PER_US, PG_GETARG_UUID_P, PG_RETURN_NULL, PG_RETURN_TIMESTAMPTZ, POSTGRES_EPOCH_JDATE, SECS_PER_DAY, UNIX_EPOCH_JDATE, and USECS_PER_SEC.

◆ uuid_extract_version()

Datum uuid_extract_version ( PG_FUNCTION_ARGS  )

Definition at line 701 of file uuid.c.

702{
703 pg_uuid_t *uuid = PG_GETARG_UUID_P(0);
704 uint16 version;
705
706 /* check if RFC 9562 variant */
707 if ((uuid->data[8] & 0xc0) != 0x80)
709
710 version = uuid->data[6] >> 4;
711
712 PG_RETURN_UINT16(version);
713}
uint16_t uint16
Definition: c.h:487
#define PG_RETURN_UINT16(x)
Definition: fmgr.h:357

References pg_uuid_t::data, PG_GETARG_UUID_P, PG_RETURN_NULL, and PG_RETURN_UINT16.

◆ uuid_fast_cmp()

static int uuid_fast_cmp ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 309 of file uuid.c.

310{
311 pg_uuid_t *arg1 = DatumGetUUIDP(x);
312 pg_uuid_t *arg2 = DatumGetUUIDP(y);
313
314 return uuid_internal_cmp(arg1, arg2);
315}
int y
Definition: isn.c:71
int x
Definition: isn.c:70

References DatumGetUUIDP(), uuid_internal_cmp(), x, and y.

Referenced by uuid_sortsupport().

◆ uuid_ge()

Datum uuid_ge ( PG_FUNCTION_ARGS  )

Definition at line 233 of file uuid.c.

234{
235 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
236 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
237
238 PG_RETURN_BOOL(uuid_internal_cmp(arg1, arg2) >= 0);
239}

References PG_GETARG_UUID_P, PG_RETURN_BOOL, and uuid_internal_cmp().

◆ uuid_gt()

Datum uuid_gt ( PG_FUNCTION_ARGS  )

Definition at line 242 of file uuid.c.

243{
244 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
245 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
246
247 PG_RETURN_BOOL(uuid_internal_cmp(arg1, arg2) > 0);
248}

References PG_GETARG_UUID_P, PG_RETURN_BOOL, and uuid_internal_cmp().

◆ uuid_hash()

Datum uuid_hash ( PG_FUNCTION_ARGS  )

Definition at line 421 of file uuid.c.

422{
424
425 return hash_any(key->data, UUID_LEN);
426}
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31

References hash_any(), sort-test::key, PG_GETARG_UUID_P, and UUID_LEN.

◆ uuid_hash_extended()

Datum uuid_hash_extended ( PG_FUNCTION_ARGS  )

Definition at line 429 of file uuid.c.

430{
432
434}
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37

References hash_any_extended(), sort-test::key, PG_GETARG_INT64, PG_GETARG_UUID_P, and UUID_LEN.

◆ uuid_in()

Datum uuid_in ( PG_FUNCTION_ARGS  )

Definition at line 74 of file uuid.c.

75{
76 char *uuid_str = PG_GETARG_CSTRING(0);
77 pg_uuid_t *uuid;
78
79 uuid = (pg_uuid_t *) palloc(sizeof(*uuid));
80 string_to_uuid(uuid_str, uuid, fcinfo->context);
81 PG_RETURN_UUID_P(uuid);
82}
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
static void string_to_uuid(const char *source, pg_uuid_t *uuid, Node *escontext)
Definition: uuid.c:127

References palloc(), PG_GETARG_CSTRING, PG_RETURN_UUID_P, and string_to_uuid().

Referenced by uuid_generate_internal().

◆ uuid_internal_cmp()

static int uuid_internal_cmp ( const pg_uuid_t arg1,
const pg_uuid_t arg2 
)
static

Definition at line 200 of file uuid.c.

201{
202 return memcmp(arg1->data, arg2->data, UUID_LEN);
203}

References pg_uuid_t::data, and UUID_LEN.

Referenced by uuid_cmp(), uuid_eq(), uuid_fast_cmp(), uuid_ge(), uuid_gt(), uuid_le(), uuid_lt(), and uuid_ne().

◆ uuid_le()

Datum uuid_le ( PG_FUNCTION_ARGS  )

Definition at line 215 of file uuid.c.

216{
217 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
218 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
219
220 PG_RETURN_BOOL(uuid_internal_cmp(arg1, arg2) <= 0);
221}

References PG_GETARG_UUID_P, PG_RETURN_BOOL, and uuid_internal_cmp().

Referenced by brin_minmax_multi_distance_uuid().

◆ uuid_lt()

Datum uuid_lt ( PG_FUNCTION_ARGS  )

Definition at line 206 of file uuid.c.

207{
208 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
209 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
210
211 PG_RETURN_BOOL(uuid_internal_cmp(arg1, arg2) < 0);
212}

References PG_GETARG_UUID_P, PG_RETURN_BOOL, and uuid_internal_cmp().

◆ uuid_ne()

Datum uuid_ne ( PG_FUNCTION_ARGS  )

Definition at line 251 of file uuid.c.

252{
253 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
254 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
255
256 PG_RETURN_BOOL(uuid_internal_cmp(arg1, arg2) != 0);
257}

References PG_GETARG_UUID_P, PG_RETURN_BOOL, and uuid_internal_cmp().

◆ uuid_out()

Datum uuid_out ( PG_FUNCTION_ARGS  )

Definition at line 85 of file uuid.c.

86{
87 pg_uuid_t *uuid = PG_GETARG_UUID_P(0);
88 static const char hex_chars[] = "0123456789abcdef";
89 char *buf,
90 *p;
91 int i;
92
93 /* counts for the four hyphens and the zero-terminator */
94 buf = palloc(2 * UUID_LEN + 5);
95 p = buf;
96 for (i = 0; i < UUID_LEN; i++)
97 {
98 int hi;
99 int lo;
100
101 /*
102 * We print uuid values as a string of 8, 4, 4, 4, and then 12
103 * hexadecimal characters, with each group is separated by a hyphen
104 * ("-"). Therefore, add the hyphens at the appropriate places here.
105 */
106 if (i == 4 || i == 6 || i == 8 || i == 10)
107 *p++ = '-';
108
109 hi = uuid->data[i] >> 4;
110 lo = uuid->data[i] & 0x0F;
111
112 *p++ = hex_chars[hi];
113 *p++ = hex_chars[lo];
114 }
115 *p = '\0';
116
118}
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
static char * buf
Definition: pg_test_fsync.c:72

References buf, pg_uuid_t::data, i, palloc(), PG_GETARG_UUID_P, PG_RETURN_CSTRING, and UUID_LEN.

◆ uuid_recv()

Datum uuid_recv ( PG_FUNCTION_ARGS  )

Definition at line 177 of file uuid.c.

178{
180 pg_uuid_t *uuid;
181
182 uuid = (pg_uuid_t *) palloc(UUID_LEN);
183 memcpy(uuid->data, pq_getmsgbytes(buffer, UUID_LEN), UUID_LEN);
184 PG_RETURN_POINTER(uuid);
185}
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:508
StringInfoData * StringInfo
Definition: stringinfo.h:54

References pg_uuid_t::data, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, pq_getmsgbytes(), and UUID_LEN.

◆ uuid_send()

Datum uuid_send ( PG_FUNCTION_ARGS  )

Definition at line 188 of file uuid.c.

189{
190 pg_uuid_t *uuid = PG_GETARG_UUID_P(0);
191 StringInfoData buffer;
192
193 pq_begintypsend(&buffer);
194 pq_sendbytes(&buffer, uuid->data, UUID_LEN);
196}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346

References pg_uuid_t::data, PG_GETARG_UUID_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendbytes(), and UUID_LEN.

◆ uuid_set_version()

static void uuid_set_version ( pg_uuid_t uuid,
unsigned char  version 
)
inlinestatic

Definition at line 440 of file uuid.c.

441{
442 /* set version field, top four bits */
443 uuid->data[6] = (uuid->data[6] & 0x0f) | (version << 4);
444
445 /* set variant field, top two bits are 1, 0 */
446 uuid->data[8] = (uuid->data[8] & 0x3f) | 0x80;
447}

References pg_uuid_t::data.

Referenced by gen_random_uuid(), and generate_uuidv7().

◆ uuid_sortsupport()

Datum uuid_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 273 of file uuid.c.

274{
276
278 ssup->ssup_extra = NULL;
279
280 if (ssup->abbreviate)
281 {
283 MemoryContext oldcontext;
284
285 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
286
287 uss = palloc(sizeof(uuid_sortsupport_state));
288 uss->input_count = 0;
289 uss->estimating = true;
290 initHyperLogLog(&uss->abbr_card, 10);
291
292 ssup->ssup_extra = uss;
293
298
299 MemoryContextSwitchTo(oldcontext);
300 }
301
303}
#define PG_RETURN_VOID()
Definition: fmgr.h:349
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
Definition: hyperloglog.c:66
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:172
MemoryContext ssup_cxt
Definition: sortsupport.h:66
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:191
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
Definition: sortsupport.h:182
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3139
static bool uuid_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: uuid.c:324
static int uuid_fast_cmp(Datum x, Datum y, SortSupport ssup)
Definition: uuid.c:309
static Datum uuid_abbrev_convert(Datum original, SortSupport ssup)
Definition: uuid.c:384

References uuid_sortsupport_state::abbr_card, SortSupportData::abbrev_abort, SortSupportData::abbrev_converter, SortSupportData::abbrev_full_comparator, SortSupportData::abbreviate, SortSupportData::comparator, uuid_sortsupport_state::estimating, initHyperLogLog(), uuid_sortsupport_state::input_count, MemoryContextSwitchTo(), palloc(), PG_GETARG_POINTER, PG_RETURN_VOID, SortSupportData::ssup_cxt, ssup_datum_unsigned_cmp(), SortSupportData::ssup_extra, uuid_abbrev_abort(), uuid_abbrev_convert(), and uuid_fast_cmp().

◆ uuidv7()

Datum uuidv7 ( PG_FUNCTION_ARGS  )

Definition at line 587 of file uuid.c.

588{
590
591 PG_RETURN_UUID_P(uuid);
592}
static int64 get_real_time_ns_ascending()
Definition: uuid.c:480
static pg_uuid_t * generate_uuidv7(int64 ns)
Definition: uuid.c:530

References generate_uuidv7(), get_real_time_ns_ascending(), and PG_RETURN_UUID_P.

◆ uuidv7_interval()

Datum uuidv7_interval ( PG_FUNCTION_ARGS  )

Definition at line 598 of file uuid.c.

599{
600 Interval *shift = PG_GETARG_INTERVAL_P(0);
601 TimestampTz ts;
602 pg_uuid_t *uuid;
604
605 /*
606 * Shift the current timestamp by the given interval. To calculate time
607 * shift correctly, we convert the UNIX epoch to TimestampTz and use
608 * timestamptz_pl_interval(). Since this calculation is done with
609 * microsecond precision, we carry nanoseconds from original ns value to
610 * shifted ns value.
611 */
612
613 ts = (TimestampTz) (ns / NS_PER_US) -
615
616 /* Compute time shift */
619 IntervalPGetDatum(shift)));
620
621 /*
622 * Convert a TimestampTz value back to an UNIX epoch and back nanoseconds.
623 */
625 * NS_PER_US + ns % NS_PER_US;
626
627 /* Generate an UUIDv7 */
628 uuid = generate_uuidv7(ns);
629
630 PG_RETURN_UUID_P(uuid);
631}
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3332
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:643
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
static Datum IntervalPGetDatum(const Interval *X)
Definition: timestamp.h:58
#define PG_GETARG_INTERVAL_P(n)
Definition: timestamp.h:65
static TimestampTz DatumGetTimestampTz(Datum X)
Definition: timestamp.h:34

References DatumGetTimestampTz(), DirectFunctionCall2, generate_uuidv7(), get_real_time_ns_ascending(), IntervalPGetDatum(), NS_PER_US, PG_GETARG_INTERVAL_P, PG_RETURN_UUID_P, POSTGRES_EPOCH_JDATE, SECS_PER_DAY, timestamptz_pl_interval(), TimestampTzGetDatum(), UNIX_EPOCH_JDATE, and USECS_PER_SEC.