PostgreSQL Source Code git master
uuid.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * uuid.c
4 * Functions for the built-in type "uuid".
5 *
6 * Copyright (c) 2007-2025, PostgreSQL Global Development Group
7 *
8 * IDENTIFICATION
9 * src/backend/utils/adt/uuid.c
10 *
11 *-------------------------------------------------------------------------
12 */
13
14#include "postgres.h"
15
16#include <time.h> /* for clock_gettime() */
17
18#include "common/hashfn.h"
19#include "lib/hyperloglog.h"
20#include "libpq/pqformat.h"
21#include "port/pg_bswap.h"
22#include "utils/fmgrprotos.h"
23#include "utils/guc.h"
24#include "utils/sortsupport.h"
25#include "utils/timestamp.h"
26#include "utils/uuid.h"
27
28/* helper macros */
29#define NS_PER_S INT64CONST(1000000000)
30#define NS_PER_MS INT64CONST(1000000)
31#define NS_PER_US INT64CONST(1000)
32
33/*
34 * UUID version 7 uses 12 bits in "rand_a" to store 1/4096 (or 2^12) fractions of
35 * sub-millisecond. While most Unix-like platforms provide nanosecond-precision
36 * timestamps, some systems only offer microsecond precision, limiting us to 10
37 * bits of sub-millisecond information. For example, on macOS, real time is
38 * truncated to microseconds. Additionally, MSVC uses the ported version of
39 * gettimeofday() that returns microsecond precision.
40 *
41 * On systems with only 10 bits of sub-millisecond precision, we still use
42 * 1/4096 parts of a millisecond, but fill lower 2 bits with random numbers
43 * (see generate_uuidv7() for details).
44 *
45 * SUBMS_MINIMAL_STEP_NS defines the minimum number of nanoseconds that guarantees
46 * an increase in the UUID's clock precision.
47 */
48#if defined(__darwin__) || defined(_MSC_VER)
49#define SUBMS_MINIMAL_STEP_BITS 10
50#else
51#define SUBMS_MINIMAL_STEP_BITS 12
52#endif
53#define SUBMS_BITS 12
54#define SUBMS_MINIMAL_STEP_NS ((NS_PER_MS / (1 << SUBMS_MINIMAL_STEP_BITS)) + 1)
55
56/* sortsupport for uuid */
57typedef struct
58{
59 int64 input_count; /* number of non-null values seen */
60 bool estimating; /* true if estimating cardinality */
61
62 hyperLogLogState abbr_card; /* cardinality estimator */
64
65static void string_to_uuid(const char *source, pg_uuid_t *uuid, Node *escontext);
66static int uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2);
67static int uuid_fast_cmp(Datum x, Datum y, SortSupport ssup);
68static bool uuid_abbrev_abort(int memtupcount, SortSupport ssup);
69static Datum uuid_abbrev_convert(Datum original, SortSupport ssup);
70static inline void uuid_set_version(pg_uuid_t *uuid, unsigned char version);
71static inline int64 get_real_time_ns_ascending();
72
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}
83
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}
119
120/*
121 * We allow UUIDs as a series of 32 hexadecimal digits with an optional dash
122 * after each group of 4 hexadecimal digits, and optionally surrounded by {}.
123 * (The canonical format 8x-4x-4x-4x-12x, where "nx" means n hexadecimal
124 * digits, is the only one used for output.)
125 */
126static void
127string_to_uuid(const char *source, pg_uuid_t *uuid, Node *escontext)
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}
175
176Datum
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}
186
187Datum
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}
197
198/* internal uuid compare function */
199static int
200uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2)
201{
202 return memcmp(arg1->data, arg2->data, UUID_LEN);
203}
204
205Datum
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}
213
214Datum
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}
222
223Datum
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}
231
232Datum
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}
240
241Datum
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}
249
250Datum
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}
258
259/* handler for btree index operator */
260Datum
262{
263 pg_uuid_t *arg1 = PG_GETARG_UUID_P(0);
264 pg_uuid_t *arg2 = PG_GETARG_UUID_P(1);
265
267}
268
269/*
270 * Sort support strategy routine
271 */
272Datum
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}
304
305/*
306 * SortSupport comparison func
307 */
308static int
310{
311 pg_uuid_t *arg1 = DatumGetUUIDP(x);
312 pg_uuid_t *arg2 = DatumGetUUIDP(y);
313
314 return uuid_internal_cmp(arg1, arg2);
315}
316
317/*
318 * Callback for estimating effectiveness of abbreviated key optimization.
319 *
320 * We pay no attention to the cardinality of the non-abbreviated data, because
321 * there is no equality fast-path within authoritative uuid comparator.
322 */
323static bool
324uuid_abbrev_abort(int memtupcount, SortSupport ssup)
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}
375
376/*
377 * Conversion routine for sortsupport. Converts original uuid representation
378 * to abbreviated key representation. Our encoding strategy is simple -- pack
379 * the first `sizeof(Datum)` bytes of uuid data into a Datum (on little-endian
380 * machines, the bytes are stored in reverse order), and treat it as an
381 * unsigned integer.
382 */
383static Datum
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}
418
419/* hash index support */
420Datum
422{
424
425 return hash_any(key->data, UUID_LEN);
426}
427
428Datum
430{
432
434}
435
436/*
437 * Set the given UUID version and the variant bits
438 */
439static inline void
440uuid_set_version(pg_uuid_t *uuid, unsigned char version)
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}
448
449/*
450 * Generate UUID version 4.
451 *
452 * All UUID bytes are filled with strong random numbers except version and
453 * variant bits.
454 */
455Datum
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}
473
474/*
475 * Get the current timestamp with nanosecond precision for UUID generation.
476 * The returned timestamp is ensured to be at least SUBMS_MINIMAL_STEP greater
477 * than the previous returned timestamp (on this backend).
478 */
479static inline int64
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}
515
516/*
517 * Generate UUID version 7 per RFC 9562, with the given timestamp.
518 *
519 * UUID version 7 consists of a Unix timestamp in milliseconds (48 bits) and
520 * 74 random bits, excluding the required version and variant bits. To ensure
521 * monotonicity in scenarios of high-frequency UUID generation, we employ the
522 * method "Replace Leftmost Random Bits with Increased Clock Precision (Method 3)",
523 * described in the RFC. This method utilizes 12 bits from the "rand_a" bits
524 * to store a 1/4096 (or 2^12) fraction of sub-millisecond precision.
525 *
526 * ns is a number of nanoseconds since start of the UNIX epoch. This value is
527 * used for time-dependent bits of UUID.
528 */
529static pg_uuid_t *
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}
582
583/*
584 * Generate UUID version 7 with the current timestamp.
585 */
586Datum
588{
590
591 PG_RETURN_UUID_P(uuid);
592}
593
594/*
595 * Similar to uuidv7() but with the timestamp adjusted by the given interval.
596 */
597Datum
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}
632
633/*
634 * Start of a Gregorian epoch == date2j(1582,10,15)
635 * We cast it to 64-bit because it's used in overflow-prone computations
636 */
637#define GREGORIAN_EPOCH_JDATE INT64CONST(2299161)
638
639/*
640 * Extract timestamp from UUID.
641 *
642 * Returns null if not RFC 9562 variant or not a version that has a timestamp.
643 */
644Datum
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}
694
695/*
696 * Extract UUID version.
697 *
698 * Returns null if not RFC 9562 variant.
699 */
700Datum
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}
Datum timestamptz_pl_interval(PG_FUNCTION_ARGS)
Definition: timestamp.c:3332
#define INT64_FORMAT
Definition: c.h:506
int64_t int64
Definition: c.h:485
int32_t int32
Definition: c.h:484
uint64_t uint64
Definition: c.h:489
uint16_t uint16
Definition: c.h:487
uint32_t uint32
Definition: c.h:488
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
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:643
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_RETURN_UINT16(x)
Definition: fmgr.h:357
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
Definition: hyperloglog.c:66
double estimateHyperLogLog(hyperLogLogState *cState)
Definition: hyperloglog.c:186
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
Definition: hyperloglog.c:167
int y
Definition: isn.c:71
int x
Definition: isn.c:70
int i
Definition: isn.c:72
void * palloc(Size size)
Definition: mcxt.c:1317
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static rewind_source * source
Definition: pg_rewind.c:89
static char * buf
Definition: pg_test_fsync.c:72
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
bool pg_strong_random(void *buf, size_t len)
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:227
uintptr_t Datum
Definition: postgres.h:69
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:508
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
StringInfoData * StringInfo
Definition: stringinfo.h:54
Definition: nodes.h:129
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:172
void * ssup_extra
Definition: sortsupport.h:87
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
Definition: uuid.h:21
unsigned char data[UUID_LEN]
Definition: uuid.h:22
hyperLogLogState abbr_card
Definition: uuid.c:62
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3139
bool trace_sort
Definition: tuplesort.c:124
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
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68
static TimestampTz DatumGetTimestampTz(Datum X)
Definition: timestamp.h:34
static int64 get_real_time_ns_ascending()
Definition: uuid.c:480
#define SUBMS_BITS
Definition: uuid.c:53
Datum uuid_send(PG_FUNCTION_ARGS)
Definition: uuid.c:188
static void string_to_uuid(const char *source, pg_uuid_t *uuid, Node *escontext)
Definition: uuid.c:127
static bool uuid_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: uuid.c:324
#define GREGORIAN_EPOCH_JDATE
Definition: uuid.c:637
Datum uuidv7_interval(PG_FUNCTION_ARGS)
Definition: uuid.c:598
Datum uuid_lt(PG_FUNCTION_ARGS)
Definition: uuid.c:206
Datum uuid_gt(PG_FUNCTION_ARGS)
Definition: uuid.c:242
Datum gen_random_uuid(PG_FUNCTION_ARGS)
Definition: uuid.c:456
Datum uuid_recv(PG_FUNCTION_ARGS)
Definition: uuid.c:177
Datum uuid_cmp(PG_FUNCTION_ARGS)
Definition: uuid.c:261
#define NS_PER_MS
Definition: uuid.c:30
static void uuid_set_version(pg_uuid_t *uuid, unsigned char version)
Definition: uuid.c:440
Datum uuid_le(PG_FUNCTION_ARGS)
Definition: uuid.c:215
static pg_uuid_t * generate_uuidv7(int64 ns)
Definition: uuid.c:530
#define SUBMS_MINIMAL_STEP_NS
Definition: uuid.c:54
Datum uuid_hash(PG_FUNCTION_ARGS)
Definition: uuid.c:421
#define NS_PER_S
Definition: uuid.c:29
Datum uuid_extract_version(PG_FUNCTION_ARGS)
Definition: uuid.c:701
Datum uuid_hash_extended(PG_FUNCTION_ARGS)
Definition: uuid.c:429
Datum uuid_out(PG_FUNCTION_ARGS)
Definition: uuid.c:85
Datum uuid_ne(PG_FUNCTION_ARGS)
Definition: uuid.c:251
static int uuid_internal_cmp(const pg_uuid_t *arg1, const pg_uuid_t *arg2)
Definition: uuid.c:200
Datum uuid_ge(PG_FUNCTION_ARGS)
Definition: uuid.c:233
Datum uuid_eq(PG_FUNCTION_ARGS)
Definition: uuid.c:224
#define NS_PER_US
Definition: uuid.c:31
static int uuid_fast_cmp(Datum x, Datum y, SortSupport ssup)
Definition: uuid.c:309
Datum uuid_in(PG_FUNCTION_ARGS)
Definition: uuid.c:74
static Datum uuid_abbrev_convert(Datum original, SortSupport ssup)
Definition: uuid.c:384
Datum uuidv7(PG_FUNCTION_ARGS)
Definition: uuid.c:587
Datum uuid_extract_timestamp(PG_FUNCTION_ARGS)
Definition: uuid.c:645
Datum uuid_sortsupport(PG_FUNCTION_ARGS)
Definition: uuid.c:273
static pg_uuid_t * DatumGetUUIDP(Datum X)
Definition: uuid.h:35
#define PG_RETURN_UUID_P(X)
Definition: uuid.h:32
#define UUID_LEN
Definition: uuid.h:18
#define PG_GETARG_UUID_P(X)
Definition: uuid.h:40
int gettimeofday(struct timeval *tp, void *tzp)