PostgreSQL Source Code git master
bytea.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * bytea.c
4 * Functions for the bytea type.
5 *
6 * Portions Copyright (c) 2025, PostgreSQL Global Development Group
7 *
8 *
9 * IDENTIFICATION
10 * src/backend/utils/adt/bytea.c
11 *
12 *-------------------------------------------------------------------------
13 */
14
15#include "postgres.h"
16
17#include "access/detoast.h"
18#include "common/hashfn.h"
19#include "common/int.h"
20#include "fmgr.h"
21#include "lib/hyperloglog.h"
22#include "libpq/pqformat.h"
23#include "port/pg_bitutils.h"
24#include "port/pg_bswap.h"
25#include "utils/builtins.h"
26#include "utils/bytea.h"
27#include "utils/fmgrprotos.h"
28#include "utils/guc.h"
29#include "utils/memutils.h"
30#include "utils/sortsupport.h"
31#include "varatt.h"
32
33/* GUC variable */
35
36static bytea *bytea_catenate(bytea *t1, bytea *t2);
37static bytea *bytea_substring(Datum str, int S, int L,
38 bool length_not_specified);
39static bytea *bytea_overlay(bytea *t1, bytea *t2, int sp, int sl);
40
41typedef struct
42{
43 bool abbreviate; /* Should we abbreviate keys? */
44 hyperLogLogState abbr_card; /* Abbreviated key cardinality state */
45 hyperLogLogState full_card; /* Full key cardinality state */
46 double prop_card; /* Required cardinality proportion */
48
49/* Static function declarations for sort support */
50static int byteafastcmp(Datum x, Datum y, SortSupport ssup);
51static Datum bytea_abbrev_convert(Datum original, SortSupport ssup);
52static bool bytea_abbrev_abort(int memtupcount, SortSupport ssup);
53
54/*
55 * bytea_catenate
56 * Guts of byteacat(), broken out so it can be used by other functions
57 *
58 * Arguments can be in short-header form, but not compressed or out-of-line
59 */
60static bytea *
62{
63 bytea *result;
64 int len1,
65 len2,
66 len;
67 char *ptr;
68
69 len1 = VARSIZE_ANY_EXHDR(t1);
70 len2 = VARSIZE_ANY_EXHDR(t2);
71
72 /* paranoia ... probably should throw error instead? */
73 if (len1 < 0)
74 len1 = 0;
75 if (len2 < 0)
76 len2 = 0;
77
78 len = len1 + len2 + VARHDRSZ;
79 result = (bytea *) palloc(len);
80
81 /* Set size of result string... */
82 SET_VARSIZE(result, len);
83
84 /* Fill data field of result string... */
85 ptr = VARDATA(result);
86 if (len1 > 0)
87 memcpy(ptr, VARDATA_ANY(t1), len1);
88 if (len2 > 0)
89 memcpy(ptr + len1, VARDATA_ANY(t2), len2);
90
91 return result;
92}
93
94#define PG_STR_GET_BYTEA(str_) \
95 DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
96
97static bytea *
99 int S,
100 int L,
101 bool length_not_specified)
102{
103 int32 S1; /* adjusted start position */
104 int32 L1; /* adjusted substring length */
105 int32 E; /* end position */
106
107 /*
108 * The logic here should generally match text_substring().
109 */
110 S1 = Max(S, 1);
111
112 if (length_not_specified)
113 {
114 /*
115 * Not passed a length - DatumGetByteaPSlice() grabs everything to the
116 * end of the string if we pass it a negative value for length.
117 */
118 L1 = -1;
119 }
120 else if (L < 0)
121 {
122 /* SQL99 says to throw an error for E < S, i.e., negative length */
124 (errcode(ERRCODE_SUBSTRING_ERROR),
125 errmsg("negative substring length not allowed")));
126 L1 = -1; /* silence stupider compilers */
127 }
128 else if (pg_add_s32_overflow(S, L, &E))
129 {
130 /*
131 * L could be large enough for S + L to overflow, in which case the
132 * substring must run to end of string.
133 */
134 L1 = -1;
135 }
136 else
137 {
138 /*
139 * A zero or negative value for the end position can happen if the
140 * start was negative or one. SQL99 says to return a zero-length
141 * string.
142 */
143 if (E < 1)
144 return PG_STR_GET_BYTEA("");
145
146 L1 = E - S1;
147 }
148
149 /*
150 * If the start position is past the end of the string, SQL99 says to
151 * return a zero-length string -- DatumGetByteaPSlice() will do that for
152 * us. We need only convert S1 to zero-based starting position.
153 */
154 return DatumGetByteaPSlice(str, S1 - 1, L1);
155}
156
157static bytea *
158bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
159{
160 bytea *result;
161 bytea *s1;
162 bytea *s2;
163 int sp_pl_sl;
164
165 /*
166 * Check for possible integer-overflow cases. For negative sp, throw a
167 * "substring length" error because that's what should be expected
168 * according to the spec's definition of OVERLAY().
169 */
170 if (sp <= 0)
172 (errcode(ERRCODE_SUBSTRING_ERROR),
173 errmsg("negative substring length not allowed")));
174 if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
176 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
177 errmsg("integer out of range")));
178
179 s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
180 s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
181 result = bytea_catenate(s1, t2);
182 result = bytea_catenate(result, s2);
183
184 return result;
185}
186
187/*****************************************************************************
188 * USER I/O ROUTINES *
189 *****************************************************************************/
190
191#define VAL(CH) ((CH) - '0')
192#define DIG(VAL) ((VAL) + '0')
193
194/*
195 * byteain - converts from printable representation of byte array
196 *
197 * Non-printable characters must be passed as '\nnn' (octal) and are
198 * converted to internal form. '\' must be passed as '\\'.
199 */
200Datum
202{
203 char *inputText = PG_GETARG_CSTRING(0);
204 Node *escontext = fcinfo->context;
205 size_t len = strlen(inputText);
206 size_t bc;
207 char *tp;
208 char *rp;
209 bytea *result;
210
211 /* Recognize hex input */
212 if (inputText[0] == '\\' && inputText[1] == 'x')
213 {
214 bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */
215 result = palloc(bc);
216 bc = hex_decode_safe(inputText + 2, len - 2, VARDATA(result),
217 escontext);
218 SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
219
220 PG_RETURN_BYTEA_P(result);
221 }
222
223 /* Else, it's the traditional escaped style */
224 result = (bytea *) palloc(len + VARHDRSZ); /* maximum possible length */
225
226 tp = inputText;
227 rp = VARDATA(result);
228 while (*tp != '\0')
229 {
230 if (tp[0] != '\\')
231 *rp++ = *tp++;
232 else if ((tp[1] >= '0' && tp[1] <= '3') &&
233 (tp[2] >= '0' && tp[2] <= '7') &&
234 (tp[3] >= '0' && tp[3] <= '7'))
235 {
236 int v;
237
238 v = VAL(tp[1]);
239 v <<= 3;
240 v += VAL(tp[2]);
241 v <<= 3;
242 *rp++ = v + VAL(tp[3]);
243
244 tp += 4;
245 }
246 else if (tp[1] == '\\')
247 {
248 *rp++ = '\\';
249 tp += 2;
250 }
251 else
252 {
253 /*
254 * one backslash, not followed by another or ### valid octal
255 */
256 ereturn(escontext, (Datum) 0,
257 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
258 errmsg("invalid input syntax for type %s", "bytea")));
259 }
260 }
261
262 bc = rp - VARDATA(result); /* actual length */
263 SET_VARSIZE(result, bc + VARHDRSZ);
264
265 PG_RETURN_BYTEA_P(result);
266}
267
268/*
269 * byteaout - converts to printable representation of byte array
270 *
271 * In the traditional escaped format, non-printable characters are
272 * printed as '\nnn' (octal) and '\' as '\\'.
273 */
274Datum
276{
277 bytea *vlena = PG_GETARG_BYTEA_PP(0);
278 char *result;
279 char *rp;
280
282 {
283 /* Print hex format */
284 rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
285 *rp++ = '\\';
286 *rp++ = 'x';
287 rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
288 }
290 {
291 /* Print traditional escaped format */
292 char *vp;
293 uint64 len;
294 int i;
295
296 len = 1; /* empty string has 1 char */
297 vp = VARDATA_ANY(vlena);
298 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
299 {
300 if (*vp == '\\')
301 len += 2;
302 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
303 len += 4;
304 else
305 len++;
306 }
307
308 /*
309 * In principle len can't overflow uint32 if the input fit in 1GB, but
310 * for safety let's check rather than relying on palloc's internal
311 * check.
312 */
313 if (len > MaxAllocSize)
315 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
316 errmsg_internal("result of bytea output conversion is too large")));
317 rp = result = (char *) palloc(len);
318
319 vp = VARDATA_ANY(vlena);
320 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
321 {
322 if (*vp == '\\')
323 {
324 *rp++ = '\\';
325 *rp++ = '\\';
326 }
327 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
328 {
329 int val; /* holds unprintable chars */
330
331 val = *vp;
332 rp[0] = '\\';
333 rp[3] = DIG(val & 07);
334 val >>= 3;
335 rp[2] = DIG(val & 07);
336 val >>= 3;
337 rp[1] = DIG(val & 03);
338 rp += 4;
339 }
340 else
341 *rp++ = *vp;
342 }
343 }
344 else
345 {
346 elog(ERROR, "unrecognized \"bytea_output\" setting: %d",
348 rp = result = NULL; /* keep compiler quiet */
349 }
350 *rp = '\0';
351 PG_RETURN_CSTRING(result);
352}
353
354/*
355 * bytearecv - converts external binary format to bytea
356 */
357Datum
359{
361 bytea *result;
362 int nbytes;
363
364 nbytes = buf->len - buf->cursor;
365 result = (bytea *) palloc(nbytes + VARHDRSZ);
366 SET_VARSIZE(result, nbytes + VARHDRSZ);
367 pq_copymsgbytes(buf, VARDATA(result), nbytes);
368 PG_RETURN_BYTEA_P(result);
369}
370
371/*
372 * byteasend - converts bytea to binary format
373 *
374 * This is a special case: just copy the input...
375 */
376Datum
378{
379 bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
380
381 PG_RETURN_BYTEA_P(vlena);
382}
383
384Datum
386{
388
390
391 /* Append the value unless null, preceding it with the delimiter. */
392 if (!PG_ARGISNULL(1))
393 {
395 bool isfirst = false;
396
397 /*
398 * You might think we can just throw away the first delimiter, however
399 * we must keep it as we may be a parallel worker doing partial
400 * aggregation building a state to send to the main process. We need
401 * to keep the delimiter of every aggregation so that the combine
402 * function can properly join up the strings of two separately
403 * partially aggregated results. The first delimiter is only stripped
404 * off in the final function. To know how much to strip off the front
405 * of the string, we store the length of the first delimiter in the
406 * StringInfo's cursor field, which we don't otherwise need here.
407 */
408 if (state == NULL)
409 {
410 MemoryContext aggcontext;
411 MemoryContext oldcontext;
412
413 if (!AggCheckCallContext(fcinfo, &aggcontext))
414 {
415 /* cannot be called directly because of internal-type argument */
416 elog(ERROR, "bytea_string_agg_transfn called in non-aggregate context");
417 }
418
419 /*
420 * Create state in aggregate context. It'll stay there across
421 * subsequent calls.
422 */
423 oldcontext = MemoryContextSwitchTo(aggcontext);
425 MemoryContextSwitchTo(oldcontext);
426
427 isfirst = true;
428 }
429
430 if (!PG_ARGISNULL(2))
431 {
432 bytea *delim = PG_GETARG_BYTEA_PP(2);
433
435 VARSIZE_ANY_EXHDR(delim));
436 if (isfirst)
437 state->cursor = VARSIZE_ANY_EXHDR(delim);
438 }
439
442 }
443
444 /*
445 * The transition type for string_agg() is declared to be "internal",
446 * which is a pass-by-value type the same size as a pointer.
447 */
448 if (state)
451}
452
453Datum
455{
457
458 /* cannot be called directly because of internal-type argument */
459 Assert(AggCheckCallContext(fcinfo, NULL));
460
462
463 if (state != NULL)
464 {
465 /* As per comment in transfn, strip data before the cursor position */
466 bytea *result;
467 int strippedlen = state->len - state->cursor;
468
469 result = (bytea *) palloc(strippedlen + VARHDRSZ);
470 SET_VARSIZE(result, strippedlen + VARHDRSZ);
471 memcpy(VARDATA(result), &state->data[state->cursor], strippedlen);
472 PG_RETURN_BYTEA_P(result);
473 }
474 else
476}
477
478/*-------------------------------------------------------------
479 * byteaoctetlen
480 *
481 * get the number of bytes contained in an instance of type 'bytea'
482 *-------------------------------------------------------------
483 */
484Datum
486{
488
489 /* We need not detoast the input at all */
491}
492
493/*
494 * byteacat -
495 * takes two bytea* and returns a bytea* that is the concatenation of
496 * the two.
497 *
498 * Cloned from textcat and modified as required.
499 */
500Datum
502{
503 bytea *t1 = PG_GETARG_BYTEA_PP(0);
504 bytea *t2 = PG_GETARG_BYTEA_PP(1);
505
507}
508
509/*
510 * byteaoverlay
511 * Replace specified substring of first string with second
512 *
513 * The SQL standard defines OVERLAY() in terms of substring and concatenation.
514 * This code is a direct implementation of what the standard says.
515 */
516Datum
518{
519 bytea *t1 = PG_GETARG_BYTEA_PP(0);
520 bytea *t2 = PG_GETARG_BYTEA_PP(1);
521 int sp = PG_GETARG_INT32(2); /* substring start position */
522 int sl = PG_GETARG_INT32(3); /* substring length */
523
524 PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
525}
526
527Datum
529{
530 bytea *t1 = PG_GETARG_BYTEA_PP(0);
531 bytea *t2 = PG_GETARG_BYTEA_PP(1);
532 int sp = PG_GETARG_INT32(2); /* substring start position */
533 int sl;
534
535 sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
536 PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
537}
538
539/*
540 * bytea_substr()
541 * Return a substring starting at the specified position.
542 * Cloned from text_substr and modified as required.
543 *
544 * Input:
545 * - string
546 * - starting position (is one-based)
547 * - string length (optional)
548 *
549 * If the starting position is zero or less, then return from the start of the string
550 * adjusting the length to be consistent with the "negative start" per SQL.
551 * If the length is less than zero, an ERROR is thrown. If no third argument
552 * (length) is provided, the length to the end of the string is assumed.
553 */
554Datum
556{
560 false));
561}
562
563/*
564 * bytea_substr_no_len -
565 * Wrapper to avoid opr_sanity failure due to
566 * one function accepting a different number of args.
567 */
568Datum
570{
573 -1,
574 true));
575}
576
577/*
578 * bit_count
579 */
580Datum
582{
583 bytea *t1 = PG_GETARG_BYTEA_PP(0);
584
586}
587
588/*
589 * byteapos -
590 * Return the position of the specified substring.
591 * Implements the SQL POSITION() function.
592 * Cloned from textpos and modified as required.
593 */
594Datum
596{
597 bytea *t1 = PG_GETARG_BYTEA_PP(0);
598 bytea *t2 = PG_GETARG_BYTEA_PP(1);
599 int pos;
600 int px,
601 p;
602 int len1,
603 len2;
604 char *p1,
605 *p2;
606
607 len1 = VARSIZE_ANY_EXHDR(t1);
608 len2 = VARSIZE_ANY_EXHDR(t2);
609
610 if (len2 <= 0)
611 PG_RETURN_INT32(1); /* result for empty pattern */
612
613 p1 = VARDATA_ANY(t1);
614 p2 = VARDATA_ANY(t2);
615
616 pos = 0;
617 px = (len1 - len2);
618 for (p = 0; p <= px; p++)
619 {
620 if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
621 {
622 pos = p + 1;
623 break;
624 };
625 p1++;
626 };
627
628 PG_RETURN_INT32(pos);
629}
630
631/*-------------------------------------------------------------
632 * byteaGetByte
633 *
634 * this routine treats "bytea" as an array of bytes.
635 * It returns the Nth byte (a number between 0 and 255).
636 *-------------------------------------------------------------
637 */
638Datum
640{
642 int32 n = PG_GETARG_INT32(1);
643 int len;
644 int byte;
645
647
648 if (n < 0 || n >= len)
650 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
651 errmsg("index %d out of valid range, 0..%d",
652 n, len - 1)));
653
654 byte = ((unsigned char *) VARDATA_ANY(v))[n];
655
656 PG_RETURN_INT32(byte);
657}
658
659/*-------------------------------------------------------------
660 * byteaGetBit
661 *
662 * This routine treats a "bytea" type like an array of bits.
663 * It returns the value of the Nth bit (0 or 1).
664 *
665 *-------------------------------------------------------------
666 */
667Datum
669{
671 int64 n = PG_GETARG_INT64(1);
672 int byteNo,
673 bitNo;
674 int len;
675 int byte;
676
678
679 if (n < 0 || n >= (int64) len * 8)
681 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
682 errmsg("index %" PRId64 " out of valid range, 0..%" PRId64,
683 n, (int64) len * 8 - 1)));
684
685 /* n/8 is now known < len, so safe to cast to int */
686 byteNo = (int) (n / 8);
687 bitNo = (int) (n % 8);
688
689 byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
690
691 if (byte & (1 << bitNo))
693 else
695}
696
697/*-------------------------------------------------------------
698 * byteaSetByte
699 *
700 * Given an instance of type 'bytea' creates a new one with
701 * the Nth byte set to the given value.
702 *
703 *-------------------------------------------------------------
704 */
705Datum
707{
709 int32 n = PG_GETARG_INT32(1);
710 int32 newByte = PG_GETARG_INT32(2);
711 int len;
712
713 len = VARSIZE(res) - VARHDRSZ;
714
715 if (n < 0 || n >= len)
717 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
718 errmsg("index %d out of valid range, 0..%d",
719 n, len - 1)));
720
721 /*
722 * Now set the byte.
723 */
724 ((unsigned char *) VARDATA(res))[n] = newByte;
725
727}
728
729/*-------------------------------------------------------------
730 * byteaSetBit
731 *
732 * Given an instance of type 'bytea' creates a new one with
733 * the Nth bit set to the given value.
734 *
735 *-------------------------------------------------------------
736 */
737Datum
739{
741 int64 n = PG_GETARG_INT64(1);
742 int32 newBit = PG_GETARG_INT32(2);
743 int len;
744 int oldByte,
745 newByte;
746 int byteNo,
747 bitNo;
748
749 len = VARSIZE(res) - VARHDRSZ;
750
751 if (n < 0 || n >= (int64) len * 8)
753 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
754 errmsg("index %" PRId64 " out of valid range, 0..%" PRId64,
755 n, (int64) len * 8 - 1)));
756
757 /* n/8 is now known < len, so safe to cast to int */
758 byteNo = (int) (n / 8);
759 bitNo = (int) (n % 8);
760
761 /*
762 * sanity check!
763 */
764 if (newBit != 0 && newBit != 1)
766 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
767 errmsg("new bit must be 0 or 1")));
768
769 /*
770 * Update the byte.
771 */
772 oldByte = ((unsigned char *) VARDATA(res))[byteNo];
773
774 if (newBit == 0)
775 newByte = oldByte & (~(1 << bitNo));
776 else
777 newByte = oldByte | (1 << bitNo);
778
779 ((unsigned char *) VARDATA(res))[byteNo] = newByte;
780
782}
783
784/*
785 * Return reversed bytea
786 */
787Datum
789{
791 const char *p = VARDATA_ANY(v);
792 int len = VARSIZE_ANY_EXHDR(v);
793 const char *endp = p + len;
794 bytea *result = palloc(len + VARHDRSZ);
795 char *dst = (char *) VARDATA(result) + len;
796
797 SET_VARSIZE(result, len + VARHDRSZ);
798
799 while (p < endp)
800 *(--dst) = *p++;
801
802 PG_RETURN_BYTEA_P(result);
803}
804
805
806/*****************************************************************************
807 * Comparison Functions used for bytea
808 *
809 * Note: btree indexes need these routines not to leak memory; therefore,
810 * be careful to free working copies of toasted datums. Most places don't
811 * need to be so careful.
812 *****************************************************************************/
813
814Datum
816{
817 Datum arg1 = PG_GETARG_DATUM(0);
818 Datum arg2 = PG_GETARG_DATUM(1);
819 bool result;
820 Size len1,
821 len2;
822
823 /*
824 * We can use a fast path for unequal lengths, which might save us from
825 * having to detoast one or both values.
826 */
827 len1 = toast_raw_datum_size(arg1);
828 len2 = toast_raw_datum_size(arg2);
829 if (len1 != len2)
830 result = false;
831 else
832 {
833 bytea *barg1 = DatumGetByteaPP(arg1);
834 bytea *barg2 = DatumGetByteaPP(arg2);
835
836 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
837 len1 - VARHDRSZ) == 0);
838
839 PG_FREE_IF_COPY(barg1, 0);
840 PG_FREE_IF_COPY(barg2, 1);
841 }
842
843 PG_RETURN_BOOL(result);
844}
845
846Datum
848{
849 Datum arg1 = PG_GETARG_DATUM(0);
850 Datum arg2 = PG_GETARG_DATUM(1);
851 bool result;
852 Size len1,
853 len2;
854
855 /*
856 * We can use a fast path for unequal lengths, which might save us from
857 * having to detoast one or both values.
858 */
859 len1 = toast_raw_datum_size(arg1);
860 len2 = toast_raw_datum_size(arg2);
861 if (len1 != len2)
862 result = true;
863 else
864 {
865 bytea *barg1 = DatumGetByteaPP(arg1);
866 bytea *barg2 = DatumGetByteaPP(arg2);
867
868 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
869 len1 - VARHDRSZ) != 0);
870
871 PG_FREE_IF_COPY(barg1, 0);
872 PG_FREE_IF_COPY(barg2, 1);
873 }
874
875 PG_RETURN_BOOL(result);
876}
877
878Datum
880{
881 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
882 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
883 int len1,
884 len2;
885 int cmp;
886
887 len1 = VARSIZE_ANY_EXHDR(arg1);
888 len2 = VARSIZE_ANY_EXHDR(arg2);
889
890 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
891
892 PG_FREE_IF_COPY(arg1, 0);
893 PG_FREE_IF_COPY(arg2, 1);
894
895 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
896}
897
898Datum
900{
901 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
902 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
903 int len1,
904 len2;
905 int cmp;
906
907 len1 = VARSIZE_ANY_EXHDR(arg1);
908 len2 = VARSIZE_ANY_EXHDR(arg2);
909
910 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
911
912 PG_FREE_IF_COPY(arg1, 0);
913 PG_FREE_IF_COPY(arg2, 1);
914
915 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
916}
917
918Datum
920{
921 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
922 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
923 int len1,
924 len2;
925 int cmp;
926
927 len1 = VARSIZE_ANY_EXHDR(arg1);
928 len2 = VARSIZE_ANY_EXHDR(arg2);
929
930 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
931
932 PG_FREE_IF_COPY(arg1, 0);
933 PG_FREE_IF_COPY(arg2, 1);
934
935 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
936}
937
938Datum
940{
941 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
942 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
943 int len1,
944 len2;
945 int cmp;
946
947 len1 = VARSIZE_ANY_EXHDR(arg1);
948 len2 = VARSIZE_ANY_EXHDR(arg2);
949
950 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
951
952 PG_FREE_IF_COPY(arg1, 0);
953 PG_FREE_IF_COPY(arg2, 1);
954
955 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
956}
957
958Datum
960{
961 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
962 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
963 int len1,
964 len2;
965 int cmp;
966
967 len1 = VARSIZE_ANY_EXHDR(arg1);
968 len2 = VARSIZE_ANY_EXHDR(arg2);
969
970 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
971 if ((cmp == 0) && (len1 != len2))
972 cmp = (len1 < len2) ? -1 : 1;
973
974 PG_FREE_IF_COPY(arg1, 0);
975 PG_FREE_IF_COPY(arg2, 1);
976
978}
979
980Datum
982{
983 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
984 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
985 bytea *result;
986 int len1,
987 len2;
988 int cmp;
989
990 len1 = VARSIZE_ANY_EXHDR(arg1);
991 len2 = VARSIZE_ANY_EXHDR(arg2);
992
993 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
994 result = ((cmp > 0) || ((cmp == 0) && (len1 > len2)) ? arg1 : arg2);
995
996 PG_RETURN_BYTEA_P(result);
997}
998
999Datum
1001{
1002 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
1003 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
1004 bytea *result;
1005 int len1,
1006 len2;
1007 int cmp;
1008
1009 len1 = VARSIZE_ANY_EXHDR(arg1);
1010 len2 = VARSIZE_ANY_EXHDR(arg2);
1011
1012 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
1013 result = ((cmp < 0) || ((cmp == 0) && (len1 < len2)) ? arg1 : arg2);
1014
1015 PG_RETURN_BYTEA_P(result);
1016}
1017
1018/*
1019 * sortsupport comparison func
1020 */
1021static int
1023{
1024 bytea *arg1 = DatumGetByteaPP(x);
1025 bytea *arg2 = DatumGetByteaPP(y);
1026 char *a1p,
1027 *a2p;
1028 int len1,
1029 len2,
1030 result;
1031
1032 a1p = VARDATA_ANY(arg1);
1033 a2p = VARDATA_ANY(arg2);
1034
1035 len1 = VARSIZE_ANY_EXHDR(arg1);
1036 len2 = VARSIZE_ANY_EXHDR(arg2);
1037
1038 result = memcmp(a1p, a2p, Min(len1, len2));
1039 if ((result == 0) && (len1 != len2))
1040 result = (len1 < len2) ? -1 : 1;
1041
1042 /* We can't afford to leak memory here. */
1043 if (PointerGetDatum(arg1) != x)
1044 pfree(arg1);
1045 if (PointerGetDatum(arg2) != y)
1046 pfree(arg2);
1047
1048 return result;
1049}
1050
1051/*
1052 * Conversion routine for sortsupport. Converts original to abbreviated key
1053 * representation. Our encoding strategy is simple -- pack the first 8 bytes
1054 * of the bytea data into a Datum (on little-endian machines, the bytes are
1055 * stored in reverse order), and treat it as an unsigned integer.
1056 */
1057static Datum
1059{
1060 const size_t max_prefix_bytes = sizeof(Datum);
1062 bytea *authoritative = DatumGetByteaPP(original);
1063 char *authoritative_data = VARDATA_ANY(authoritative);
1064 Datum res;
1065 char *pres;
1066 int len;
1067 uint32 hash;
1068
1069 pres = (char *) &res;
1070
1071 /* memset(), so any non-overwritten bytes are NUL */
1072 memset(pres, 0, max_prefix_bytes);
1073 len = VARSIZE_ANY_EXHDR(authoritative);
1074
1075 /*
1076 * Short byteas will have terminating NUL bytes in the abbreviated datum.
1077 * Abbreviated comparison need not make a distinction between these NUL
1078 * bytes, and NUL bytes representing actual NULs in the authoritative
1079 * representation.
1080 *
1081 * Hopefully a comparison at or past one abbreviated key's terminating NUL
1082 * byte will resolve the comparison without consulting the authoritative
1083 * representation; specifically, some later non-NUL byte in the longer
1084 * bytea can resolve the comparison against a subsequent terminating NUL
1085 * in the shorter bytea. There will usually be what is effectively a
1086 * "length-wise" resolution there and then.
1087 *
1088 * If that doesn't work out -- if all bytes in the longer bytea positioned
1089 * at or past the offset of the smaller bytea (first) terminating NUL are
1090 * actually representative of NUL bytes in the authoritative binary bytea
1091 * (perhaps with some *terminating* NUL bytes towards the end of the
1092 * longer bytea iff it happens to still be small) -- then an authoritative
1093 * tie-breaker will happen, and do the right thing: explicitly consider
1094 * bytea length.
1095 */
1096 memcpy(pres, authoritative_data, Min(len, max_prefix_bytes));
1097
1098 /*
1099 * Maintain approximate cardinality of both abbreviated keys and original,
1100 * authoritative keys using HyperLogLog. Used as cheap insurance against
1101 * the worst case, where we do many string abbreviations for no saving in
1102 * full memcmp()-based comparisons. These statistics are used by
1103 * bytea_abbrev_abort().
1104 *
1105 * First, Hash key proper, or a significant fraction of it. Mix in length
1106 * in order to compensate for cases where differences are past
1107 * PG_CACHE_LINE_SIZE bytes, so as to limit the overhead of hashing.
1108 */
1109 hash = DatumGetUInt32(hash_any((unsigned char *) authoritative_data,
1111
1112 if (len > PG_CACHE_LINE_SIZE)
1114
1116
1117 /* Hash abbreviated key */
1118 {
1119 uint32 tmp;
1120
1121 tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
1123 }
1124
1126
1127 /*
1128 * Byteswap on little-endian machines.
1129 *
1130 * This is needed so that ssup_datum_unsigned_cmp() works correctly on all
1131 * platforms.
1132 */
1133 res = DatumBigEndianToNative(res);
1134
1135 /* Don't leak memory here */
1136 if (PointerGetDatum(authoritative) != original)
1137 pfree(authoritative);
1138
1139 return res;
1140}
1141
1142/*
1143 * Callback for estimating effectiveness of abbreviated key optimization, using
1144 * heuristic rules. Returns value indicating if the abbreviation optimization
1145 * should be aborted, based on its projected effectiveness.
1146 *
1147 * This is based on varstr_abbrev_abort(), but some comments have been elided
1148 * for brevity. See there for more details.
1149 */
1150static bool
1151bytea_abbrev_abort(int memtupcount, SortSupport ssup)
1152{
1154 double abbrev_distinct,
1155 key_distinct;
1156
1157 Assert(ssup->abbreviate);
1158
1159 /* Have a little patience */
1160 if (memtupcount < 100)
1161 return false;
1162
1163 abbrev_distinct = estimateHyperLogLog(&bss->abbr_card);
1164 key_distinct = estimateHyperLogLog(&bss->full_card);
1165
1166 /*
1167 * Clamp cardinality estimates to at least one distinct value. While
1168 * NULLs are generally disregarded, if only NULL values were seen so far,
1169 * that might misrepresent costs if we failed to clamp.
1170 */
1171 if (abbrev_distinct < 1.0)
1172 abbrev_distinct = 1.0;
1173
1174 if (key_distinct < 1.0)
1175 key_distinct = 1.0;
1176
1177 if (trace_sort)
1178 {
1179 double norm_abbrev_card = abbrev_distinct / (double) memtupcount;
1180
1181 elog(LOG, "bytea_abbrev: abbrev_distinct after %d: %f "
1182 "(key_distinct: %f, norm_abbrev_card: %f, prop_card: %f)",
1183 memtupcount, abbrev_distinct, key_distinct, norm_abbrev_card,
1184 bss->prop_card);
1185 }
1186
1187 /*
1188 * If the number of distinct abbreviated keys approximately matches the
1189 * number of distinct original keys, continue with abbreviation.
1190 */
1191 if (abbrev_distinct > key_distinct * bss->prop_card)
1192 {
1193 /*
1194 * Decay required cardinality aggressively after 10,000 tuples.
1195 */
1196 if (memtupcount > 10000)
1197 bss->prop_card *= 0.65;
1198
1199 return false;
1200 }
1201
1202 /*
1203 * Abort abbreviation strategy.
1204 */
1205 if (trace_sort)
1206 elog(LOG, "bytea_abbrev: aborted abbreviation at %d "
1207 "(abbrev_distinct: %f, key_distinct: %f, prop_card: %f)",
1208 memtupcount, abbrev_distinct, key_distinct, bss->prop_card);
1209
1210 return true;
1211}
1212
1213Datum
1215{
1217 MemoryContext oldcontext;
1218
1219 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1220
1221 ssup->comparator = byteafastcmp;
1222
1223 /*
1224 * Set up abbreviation support if requested.
1225 */
1226 if (ssup->abbreviate)
1227 {
1228 ByteaSortSupport *bss;
1229
1231 bss->abbreviate = true;
1232 bss->prop_card = 0.20;
1233 initHyperLogLog(&bss->abbr_card, 10);
1234 initHyperLogLog(&bss->full_card, 10);
1235
1236 ssup->ssup_extra = bss;
1237 ssup->abbrev_full_comparator = ssup->comparator;
1241 }
1242
1243 MemoryContextSwitchTo(oldcontext);
1244
1246}
1247
1248/* Cast bytea -> int2 */
1249Datum
1251{
1252 bytea *v = PG_GETARG_BYTEA_PP(0);
1253 int len = VARSIZE_ANY_EXHDR(v);
1254 uint16 result;
1255
1256 /* Check that the byte array is not too long */
1257 if (len > sizeof(result))
1258 ereport(ERROR,
1259 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1260 errmsg("smallint out of range"));
1261
1262 /* Convert it to an integer; most significant bytes come first */
1263 result = 0;
1264 for (int i = 0; i < len; i++)
1265 {
1266 result <<= BITS_PER_BYTE;
1267 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1268 }
1269
1270 PG_RETURN_INT16(result);
1271}
1272
1273/* Cast bytea -> int4 */
1274Datum
1276{
1277 bytea *v = PG_GETARG_BYTEA_PP(0);
1278 int len = VARSIZE_ANY_EXHDR(v);
1279 uint32 result;
1280
1281 /* Check that the byte array is not too long */
1282 if (len > sizeof(result))
1283 ereport(ERROR,
1284 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1285 errmsg("integer out of range"));
1286
1287 /* Convert it to an integer; most significant bytes come first */
1288 result = 0;
1289 for (int i = 0; i < len; i++)
1290 {
1291 result <<= BITS_PER_BYTE;
1292 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1293 }
1294
1295 PG_RETURN_INT32(result);
1296}
1297
1298/* Cast bytea -> int8 */
1299Datum
1301{
1302 bytea *v = PG_GETARG_BYTEA_PP(0);
1303 int len = VARSIZE_ANY_EXHDR(v);
1304 uint64 result;
1305
1306 /* Check that the byte array is not too long */
1307 if (len > sizeof(result))
1308 ereport(ERROR,
1309 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1310 errmsg("bigint out of range"));
1311
1312 /* Convert it to an integer; most significant bytes come first */
1313 result = 0;
1314 for (int i = 0; i < len; i++)
1315 {
1316 result <<= BITS_PER_BYTE;
1317 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1318 }
1319
1320 PG_RETURN_INT64(result);
1321}
1322
1323/* Cast int2 -> bytea; can just use int2send() */
1324Datum
1326{
1327 return int2send(fcinfo);
1328}
1329
1330/* Cast int4 -> bytea; can just use int4send() */
1331Datum
1333{
1334 return int4send(fcinfo);
1335}
1336
1337/* Cast int8 -> bytea; can just use int8send() */
1338Datum
1340{
1341 return int8send(fcinfo);
1342}
Datum byteacat(PG_FUNCTION_ARGS)
Definition: bytea.c:501
Datum byteaoverlay(PG_FUNCTION_ARGS)
Definition: bytea.c:517
int bytea_output
Definition: bytea.c:34
Datum byteaeq(PG_FUNCTION_ARGS)
Definition: bytea.c:815
#define DIG(VAL)
Definition: bytea.c:192
Datum byteagt(PG_FUNCTION_ARGS)
Definition: bytea.c:919
Datum bytea_int2(PG_FUNCTION_ARGS)
Definition: bytea.c:1250
Datum bytea_string_agg_finalfn(PG_FUNCTION_ARGS)
Definition: bytea.c:454
Datum int2_bytea(PG_FUNCTION_ARGS)
Definition: bytea.c:1325
Datum byteapos(PG_FUNCTION_ARGS)
Definition: bytea.c:595
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: bytea.c:158
Datum byteane(PG_FUNCTION_ARGS)
Definition: bytea.c:847
Datum byteage(PG_FUNCTION_ARGS)
Definition: bytea.c:939
Datum byteacmp(PG_FUNCTION_ARGS)
Definition: bytea.c:959
Datum byteaGetBit(PG_FUNCTION_ARGS)
Definition: bytea.c:668
Datum bytea_bit_count(PG_FUNCTION_ARGS)
Definition: bytea.c:581
Datum byteaSetBit(PG_FUNCTION_ARGS)
Definition: bytea.c:738
Datum byteaSetByte(PG_FUNCTION_ARGS)
Definition: bytea.c:706
static int byteafastcmp(Datum x, Datum y, SortSupport ssup)
Definition: bytea.c:1022
Datum bytea_substr_no_len(PG_FUNCTION_ARGS)
Definition: bytea.c:569
Datum byteale(PG_FUNCTION_ARGS)
Definition: bytea.c:899
#define PG_STR_GET_BYTEA(str_)
Definition: bytea.c:94
Datum int8_bytea(PG_FUNCTION_ARGS)
Definition: bytea.c:1339
Datum bytea_int4(PG_FUNCTION_ARGS)
Definition: bytea.c:1275
Datum bytearecv(PG_FUNCTION_ARGS)
Definition: bytea.c:358
Datum bytea_smaller(PG_FUNCTION_ARGS)
Definition: bytea.c:1000
Datum bytea_sortsupport(PG_FUNCTION_ARGS)
Definition: bytea.c:1214
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: bytea.c:98
static Datum bytea_abbrev_convert(Datum original, SortSupport ssup)
Definition: bytea.c:1058
static bool bytea_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: bytea.c:1151
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: bytea.c:61
Datum bytea_reverse(PG_FUNCTION_ARGS)
Definition: bytea.c:788
Datum byteaoverlay_no_len(PG_FUNCTION_ARGS)
Definition: bytea.c:528
Datum bytea_int8(PG_FUNCTION_ARGS)
Definition: bytea.c:1300
Datum bytea_larger(PG_FUNCTION_ARGS)
Definition: bytea.c:981
Datum byteaoctetlen(PG_FUNCTION_ARGS)
Definition: bytea.c:485
Datum byteaout(PG_FUNCTION_ARGS)
Definition: bytea.c:275
Datum byteain(PG_FUNCTION_ARGS)
Definition: bytea.c:201
Datum bytea_string_agg_transfn(PG_FUNCTION_ARGS)
Definition: bytea.c:385
Datum byteaGetByte(PG_FUNCTION_ARGS)
Definition: bytea.c:639
Datum int4_bytea(PG_FUNCTION_ARGS)
Definition: bytea.c:1332
#define VAL(CH)
Definition: bytea.c:191
Datum bytea_substr(PG_FUNCTION_ARGS)
Definition: bytea.c:555
Datum bytealt(PG_FUNCTION_ARGS)
Definition: bytea.c:879
Datum byteasend(PG_FUNCTION_ARGS)
Definition: bytea.c:377
@ BYTEA_OUTPUT_HEX
Definition: bytea.h:22
@ BYTEA_OUTPUT_ESCAPE
Definition: bytea.h:21
#define Min(x, y)
Definition: c.h:995
#define Max(x, y)
Definition: c.h:989
#define VARHDRSZ
Definition: c.h:711
int64_t int64
Definition: c.h:549
int32_t int32
Definition: c.h:548
uint64_t uint64
Definition: c.h:553
uint16_t uint16
Definition: c.h:551
uint32_t uint32
Definition: c.h:552
size_t Size
Definition: c.h:624
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1170
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define LOG
Definition: elog.h:31
#define ereturn(context, dummy_value,...)
Definition: elog.h:278
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:150
uint64 hex_decode_safe(const char *src, size_t len, char *dst, Node *escontext)
Definition: encode.c:351
uint64 hex_encode(const char *src, size_t len, char *dst)
Definition: encode.c:202
#define palloc_object(type)
Definition: fe_memutils.h:74
#define MaxAllocSize
Definition: fe_memutils.h:22
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:303
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#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_INT16(x)
Definition: fmgr.h:356
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
Assert(PointerIsAligned(start, uint64))
const char * str
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
long val
Definition: informix.c:689
static struct @171 value
Datum int8send(PG_FUNCTION_ARGS)
Definition: int8.c:94
Datum int2send(PG_FUNCTION_ARGS)
Definition: int.c:98
Datum int4send(PG_FUNCTION_ARGS)
Definition: int.c:322
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:151
int y
Definition: isn.c:76
int x
Definition: isn.c:75
int i
Definition: isn.c:77
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc(Size size)
Definition: mcxt.c:1365
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4607
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.h:363
#define DatumBigEndianToNative(x)
Definition: pg_bswap.h:145
#define BITS_PER_BYTE
#define PG_CACHE_LINE_SIZE
const void size_t len
static char buf[DEFAULT_XLOG_SEG_SIZE]
Definition: pg_test_fsync.c:71
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:232
static uint64 DatumGetUInt64(Datum X)
Definition: postgres.h:413
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:332
uint64_t Datum
Definition: postgres.h:70
void pq_copymsgbytes(StringInfo msg, void *buf, int datalen)
Definition: pqformat.c:527
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
#define S(n, x)
Definition: sha1.c:73
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
struct StringInfoData * StringInfo
Definition: string.h:15
StringInfo makeStringInfo(void)
Definition: stringinfo.c:72
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281
double prop_card
Definition: bytea.c:46
hyperLogLogState full_card
Definition: bytea.c:45
hyperLogLogState abbr_card
Definition: bytea.c:44
bool abbreviate
Definition: bytea.c:43
Definition: nodes.h:135
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: regguts.h:323
Definition: c.h:706
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3123
bool trace_sort
Definition: tuplesort.c:122
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition: varatt.h:472
static Size VARSIZE(const void *PTR)
Definition: varatt.h:298
static char * VARDATA(const void *PTR)
Definition: varatt.h:305
static char * VARDATA_ANY(const void *PTR)
Definition: varatt.h:486
static void SET_VARSIZE(void *PTR, Size len)
Definition: varatt.h:432