PostgreSQL Source Code git master
Loading...
Searching...
No Matches
bytea.c File Reference
#include "postgres.h"
#include "access/detoast.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "fmgr.h"
#include "lib/hyperloglog.h"
#include "libpq/pqformat.h"
#include "port/pg_bitutils.h"
#include "port/pg_bswap.h"
#include "utils/builtins.h"
#include "utils/bytea.h"
#include "utils/fmgrprotos.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/sortsupport.h"
#include "varatt.h"
Include dependency graph for bytea.c:

Go to the source code of this file.

Data Structures

struct  ByteaSortSupport
 

Macros

#define PG_STR_GET_BYTEA(str_)    DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
 
#define VAL(CH)   ((CH) - '0')
 
#define DIG(VAL)   ((VAL) + '0')
 

Functions

static byteabytea_catenate (bytea *t1, bytea *t2)
 
static byteabytea_substring (Datum str, int S, int L, bool length_not_specified)
 
static byteabytea_overlay (bytea *t1, bytea *t2, int sp, int sl)
 
static int byteafastcmp (Datum x, Datum y, SortSupport ssup)
 
static Datum bytea_abbrev_convert (Datum original, SortSupport ssup)
 
static bool bytea_abbrev_abort (int memtupcount, SortSupport ssup)
 
Datum byteain (PG_FUNCTION_ARGS)
 
Datum byteaout (PG_FUNCTION_ARGS)
 
Datum bytearecv (PG_FUNCTION_ARGS)
 
Datum byteasend (PG_FUNCTION_ARGS)
 
Datum bytea_string_agg_transfn (PG_FUNCTION_ARGS)
 
Datum bytea_string_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum byteaoctetlen (PG_FUNCTION_ARGS)
 
Datum byteacat (PG_FUNCTION_ARGS)
 
Datum byteaoverlay (PG_FUNCTION_ARGS)
 
Datum byteaoverlay_no_len (PG_FUNCTION_ARGS)
 
Datum bytea_substr (PG_FUNCTION_ARGS)
 
Datum bytea_substr_no_len (PG_FUNCTION_ARGS)
 
Datum bytea_bit_count (PG_FUNCTION_ARGS)
 
Datum byteapos (PG_FUNCTION_ARGS)
 
Datum byteaGetByte (PG_FUNCTION_ARGS)
 
Datum byteaGetBit (PG_FUNCTION_ARGS)
 
Datum byteaSetByte (PG_FUNCTION_ARGS)
 
Datum byteaSetBit (PG_FUNCTION_ARGS)
 
Datum bytea_reverse (PG_FUNCTION_ARGS)
 
Datum byteaeq (PG_FUNCTION_ARGS)
 
Datum byteane (PG_FUNCTION_ARGS)
 
Datum bytealt (PG_FUNCTION_ARGS)
 
Datum byteale (PG_FUNCTION_ARGS)
 
Datum byteagt (PG_FUNCTION_ARGS)
 
Datum byteage (PG_FUNCTION_ARGS)
 
Datum byteacmp (PG_FUNCTION_ARGS)
 
Datum bytea_larger (PG_FUNCTION_ARGS)
 
Datum bytea_smaller (PG_FUNCTION_ARGS)
 
Datum bytea_sortsupport (PG_FUNCTION_ARGS)
 
Datum bytea_int2 (PG_FUNCTION_ARGS)
 
Datum bytea_int4 (PG_FUNCTION_ARGS)
 
Datum bytea_int8 (PG_FUNCTION_ARGS)
 
Datum int2_bytea (PG_FUNCTION_ARGS)
 
Datum int4_bytea (PG_FUNCTION_ARGS)
 
Datum int8_bytea (PG_FUNCTION_ARGS)
 

Variables

int bytea_output = BYTEA_OUTPUT_HEX
 

Macro Definition Documentation

◆ DIG

#define DIG (   VAL)    ((VAL) + '0')

Definition at line 192 of file bytea.c.

◆ PG_STR_GET_BYTEA

Definition at line 94 of file bytea.c.

101{
102 int32 S1; /* adjusted start position */
103 int32 L1; /* adjusted substring length */
104 int32 E; /* end position */
105
106 /*
107 * The logic here should generally match text_substring().
108 */
109 S1 = Max(S, 1);
110
112 {
113 /*
114 * Not passed a length - DatumGetByteaPSlice() grabs everything to the
115 * end of the string if we pass it a negative value for length.
116 */
117 L1 = -1;
118 }
119 else if (L < 0)
120 {
121 /* SQL99 says to throw an error for E < S, i.e., negative length */
124 errmsg("negative substring length not allowed")));
125 L1 = -1; /* silence stupider compilers */
126 }
127 else if (pg_add_s32_overflow(S, L, &E))
128 {
129 /*
130 * L could be large enough for S + L to overflow, in which case the
131 * substring must run to end of string.
132 */
133 L1 = -1;
134 }
135 else
136 {
137 /*
138 * A zero or negative value for the end position can happen if the
139 * start was negative or one. SQL99 says to return a zero-length
140 * string.
141 */
142 if (E < 1)
143 return PG_STR_GET_BYTEA("");
144
145 L1 = E - S1;
146 }
147
148 /*
149 * If the start position is past the end of the string, SQL99 says to
150 * return a zero-length string -- DatumGetByteaPSlice() will do that for
151 * us. We need only convert S1 to zero-based starting position.
152 */
153 return DatumGetByteaPSlice(str, S1 - 1, L1);
154}
155
156static bytea *
157bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
158{
159 bytea *result;
160 bytea *s1;
161 bytea *s2;
162 int sp_pl_sl;
163
164 /*
165 * Check for possible integer-overflow cases. For negative sp, throw a
166 * "substring length" error because that's what should be expected
167 * according to the spec's definition of OVERLAY().
168 */
169 if (sp <= 0)
172 errmsg("negative substring length not allowed")));
176 errmsg("integer out of range")));
177
178 s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
180 result = bytea_catenate(s1, t2);
181 result = bytea_catenate(result, s2);
182
183 return result;
184}
185
186/*****************************************************************************
187 * USER I/O ROUTINES *
188 *****************************************************************************/
189
190#define VAL(CH) ((CH) - '0')
191#define DIG(VAL) ((VAL) + '0')
192
193/*
194 * byteain - converts from printable representation of byte array
195 *
196 * Non-printable characters must be passed as '\nnn' (octal) and are
197 * converted to internal form. '\' must be passed as '\\'.
198 */
199Datum
201{
202 char *inputText = PG_GETARG_CSTRING(0);
203 Node *escontext = fcinfo->context;
204 size_t len = strlen(inputText);
205 size_t bc;
206 char *tp;
207 char *rp;
208 bytea *result;
209
210 /* Recognize hex input */
211 if (inputText[0] == '\\' && inputText[1] == 'x')
212 {
213 bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */
214 result = palloc(bc);
215 bc = hex_decode_safe(inputText + 2, len - 2, VARDATA(result),
216 escontext);
217 SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
218
219 PG_RETURN_BYTEA_P(result);
220 }
221
222 /* Else, it's the traditional escaped style */
223 result = (bytea *) palloc(len + VARHDRSZ); /* maximum possible length */
224
225 tp = inputText;
226 rp = VARDATA(result);
227 while (*tp != '\0')
228 {
229 if (tp[0] != '\\')
230 *rp++ = *tp++;
231 else if ((tp[1] >= '0' && tp[1] <= '3') &&
232 (tp[2] >= '0' && tp[2] <= '7') &&
233 (tp[3] >= '0' && tp[3] <= '7'))
234 {
235 int v;
236
237 v = VAL(tp[1]);
238 v <<= 3;
239 v += VAL(tp[2]);
240 v <<= 3;
241 *rp++ = v + VAL(tp[3]);
242
243 tp += 4;
244 }
245 else if (tp[1] == '\\')
246 {
247 *rp++ = '\\';
248 tp += 2;
249 }
250 else
251 {
252 /*
253 * one backslash, not followed by another or ### valid octal
254 */
255 ereturn(escontext, (Datum) 0,
257 errmsg("invalid input syntax for type %s", "bytea")));
258 }
259 }
260
261 bc = rp - VARDATA(result); /* actual length */
262 SET_VARSIZE(result, bc + VARHDRSZ);
263
264 PG_RETURN_BYTEA_P(result);
265}
266
267/*
268 * byteaout - converts to printable representation of byte array
269 *
270 * In the traditional escaped format, non-printable characters are
271 * printed as '\nnn' (octal) and '\' as '\\'.
272 */
273Datum
275{
277 char *result;
278 char *rp;
279
281 {
282 /* Print hex format */
283 rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
284 *rp++ = '\\';
285 *rp++ = 'x';
287 }
289 {
290 /* Print traditional escaped format */
291 char *vp;
292 uint64 len;
293 int i;
294
295 len = 1; /* empty string has 1 char */
297 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
298 {
299 if (*vp == '\\')
300 len += 2;
301 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
302 len += 4;
303 else
304 len++;
305 }
306
307 /*
308 * In principle len can't overflow uint32 if the input fit in 1GB, but
309 * for safety let's check rather than relying on palloc's internal
310 * check.
311 */
312 if (len > MaxAllocSize)
315 errmsg_internal("result of bytea output conversion is too large")));
316 rp = result = (char *) palloc(len);
317
319 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
320 {
321 if (*vp == '\\')
322 {
323 *rp++ = '\\';
324 *rp++ = '\\';
325 }
326 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
327 {
328 int val; /* holds unprintable chars */
329
330 val = *vp;
331 rp[0] = '\\';
332 rp[3] = DIG(val & 07);
333 val >>= 3;
334 rp[2] = DIG(val & 07);
335 val >>= 3;
336 rp[1] = DIG(val & 03);
337 rp += 4;
338 }
339 else
340 *rp++ = *vp;
341 }
342 }
343 else
344 {
345 elog(ERROR, "unrecognized \"bytea_output\" setting: %d",
347 rp = result = NULL; /* keep compiler quiet */
348 }
349 *rp = '\0';
350 PG_RETURN_CSTRING(result);
351}
352
353/*
354 * bytearecv - converts external binary format to bytea
355 */
356Datum
358{
360 bytea *result;
361 int nbytes;
362
363 nbytes = buf->len - buf->cursor;
364 result = (bytea *) palloc(nbytes + VARHDRSZ);
365 SET_VARSIZE(result, nbytes + VARHDRSZ);
366 pq_copymsgbytes(buf, VARDATA(result), nbytes);
367 PG_RETURN_BYTEA_P(result);
368}
369
370/*
371 * byteasend - converts bytea to binary format
372 *
373 * This is a special case: just copy the input...
374 */
375Datum
377{
379
381}
382
383Datum
385{
387
389
390 /* Append the value unless null, preceding it with the delimiter. */
391 if (!PG_ARGISNULL(1))
392 {
394 bool isfirst = false;
395
396 /*
397 * You might think we can just throw away the first delimiter, however
398 * we must keep it as we may be a parallel worker doing partial
399 * aggregation building a state to send to the main process. We need
400 * to keep the delimiter of every aggregation so that the combine
401 * function can properly join up the strings of two separately
402 * partially aggregated results. The first delimiter is only stripped
403 * off in the final function. To know how much to strip off the front
404 * of the string, we store the length of the first delimiter in the
405 * StringInfo's cursor field, which we don't otherwise need here.
406 */
407 if (state == NULL)
408 {
409 MemoryContext aggcontext;
410 MemoryContext oldcontext;
411
412 if (!AggCheckCallContext(fcinfo, &aggcontext))
413 {
414 /* cannot be called directly because of internal-type argument */
415 elog(ERROR, "bytea_string_agg_transfn called in non-aggregate context");
416 }
417
418 /*
419 * Create state in aggregate context. It'll stay there across
420 * subsequent calls.
421 */
422 oldcontext = MemoryContextSwitchTo(aggcontext);
424 MemoryContextSwitchTo(oldcontext);
425
426 isfirst = true;
427 }
428
429 if (!PG_ARGISNULL(2))
430 {
431 bytea *delim = PG_GETARG_BYTEA_PP(2);
432
434 VARSIZE_ANY_EXHDR(delim));
435 if (isfirst)
436 state->cursor = VARSIZE_ANY_EXHDR(delim);
437 }
438
441 }
442
443 /*
444 * The transition type for string_agg() is declared to be "internal",
445 * which is a pass-by-value type the same size as a pointer.
446 */
447 if (state)
450}
451
452Datum
454{
456
457 /* cannot be called directly because of internal-type argument */
459
461
462 if (state != NULL)
463 {
464 /* As per comment in transfn, strip data before the cursor position */
465 bytea *result;
466 int strippedlen = state->len - state->cursor;
467
468 result = (bytea *) palloc(strippedlen + VARHDRSZ);
470 memcpy(VARDATA(result), &state->data[state->cursor], strippedlen);
471 PG_RETURN_BYTEA_P(result);
472 }
473 else
475}
476
477/*-------------------------------------------------------------
478 * byteaoctetlen
479 *
480 * get the number of bytes contained in an instance of type 'bytea'
481 *-------------------------------------------------------------
482 */
483Datum
485{
487
488 /* We need not detoast the input at all */
490}
491
492/*
493 * byteacat -
494 * takes two bytea* and returns a bytea* that is the concatenation of
495 * the two.
496 *
497 * Cloned from textcat and modified as required.
498 */
499Datum
501{
504
506}
507
508/*
509 * byteaoverlay
510 * Replace specified substring of first string with second
511 *
512 * The SQL standard defines OVERLAY() in terms of substring and concatenation.
513 * This code is a direct implementation of what the standard says.
514 */
515Datum
517{
520 int sp = PG_GETARG_INT32(2); /* substring start position */
521 int sl = PG_GETARG_INT32(3); /* substring length */
522
524}
525
526Datum
528{
531 int sp = PG_GETARG_INT32(2); /* substring start position */
532 int sl;
533
534 sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
536}
537
538/*
539 * bytea_substr()
540 * Return a substring starting at the specified position.
541 * Cloned from text_substr and modified as required.
542 *
543 * Input:
544 * - string
545 * - starting position (is one-based)
546 * - string length (optional)
547 *
548 * If the starting position is zero or less, then return from the start of the string
549 * adjusting the length to be consistent with the "negative start" per SQL.
550 * If the length is less than zero, an ERROR is thrown. If no third argument
551 * (length) is provided, the length to the end of the string is assumed.
552 */
553Datum
555{
559 false));
560}
561
562/*
563 * bytea_substr_no_len -
564 * Wrapper to avoid opr_sanity failure due to
565 * one function accepting a different number of args.
566 */
567Datum
569{
572 -1,
573 true));
574}
575
576/*
577 * bit_count
578 */
579Datum
581{
583
585}
586
587/*
588 * byteapos -
589 * Return the position of the specified substring.
590 * Implements the SQL POSITION() function.
591 * Cloned from textpos and modified as required.
592 */
593Datum
595{
598 int pos;
599 int px,
600 p;
601 int len1,
602 len2;
603 char *p1,
604 *p2;
605
606 len1 = VARSIZE_ANY_EXHDR(t1);
607 len2 = VARSIZE_ANY_EXHDR(t2);
608
609 if (len2 <= 0)
610 PG_RETURN_INT32(1); /* result for empty pattern */
611
612 p1 = VARDATA_ANY(t1);
613 p2 = VARDATA_ANY(t2);
614
615 pos = 0;
616 px = (len1 - len2);
617 for (p = 0; p <= px; p++)
618 {
619 if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
620 {
621 pos = p + 1;
622 break;
623 };
624 p1++;
625 };
626
627 PG_RETURN_INT32(pos);
628}
629
630/*-------------------------------------------------------------
631 * byteaGetByte
632 *
633 * this routine treats "bytea" as an array of bytes.
634 * It returns the Nth byte (a number between 0 and 255).
635 *-------------------------------------------------------------
636 */
637Datum
639{
641 int32 n = PG_GETARG_INT32(1);
642 int len;
643 int byte;
644
646
647 if (n < 0 || n >= len)
650 errmsg("index %d out of valid range, 0..%d",
651 n, len - 1)));
652
653 byte = ((unsigned char *) VARDATA_ANY(v))[n];
654
655 PG_RETURN_INT32(byte);
656}
657
658/*-------------------------------------------------------------
659 * byteaGetBit
660 *
661 * This routine treats a "bytea" type like an array of bits.
662 * It returns the value of the Nth bit (0 or 1).
663 *
664 *-------------------------------------------------------------
665 */
666Datum
668{
670 int64 n = PG_GETARG_INT64(1);
671 int byteNo,
672 bitNo;
673 int len;
674 int byte;
675
677
678 if (n < 0 || n >= (int64) len * 8)
681 errmsg("index %" PRId64 " out of valid range, 0..%" PRId64,
682 n, (int64) len * 8 - 1)));
683
684 /* n/8 is now known < len, so safe to cast to int */
685 byteNo = (int) (n / 8);
686 bitNo = (int) (n % 8);
687
688 byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
689
690 if (byte & (1 << bitNo))
692 else
694}
695
696/*-------------------------------------------------------------
697 * byteaSetByte
698 *
699 * Given an instance of type 'bytea' creates a new one with
700 * the Nth byte set to the given value.
701 *
702 *-------------------------------------------------------------
703 */
704Datum
706{
708 int32 n = PG_GETARG_INT32(1);
710 int len;
711
712 len = VARSIZE(res) - VARHDRSZ;
713
714 if (n < 0 || n >= len)
717 errmsg("index %d out of valid range, 0..%d",
718 n, len - 1)));
719
720 /*
721 * Now set the byte.
722 */
723 ((unsigned char *) VARDATA(res))[n] = newByte;
724
726}
727
728/*-------------------------------------------------------------
729 * byteaSetBit
730 *
731 * Given an instance of type 'bytea' creates a new one with
732 * the Nth bit set to the given value.
733 *
734 *-------------------------------------------------------------
735 */
736Datum
738{
740 int64 n = PG_GETARG_INT64(1);
742 int len;
743 int oldByte,
744 newByte;
745 int byteNo,
746 bitNo;
747
748 len = VARSIZE(res) - VARHDRSZ;
749
750 if (n < 0 || n >= (int64) len * 8)
753 errmsg("index %" PRId64 " out of valid range, 0..%" PRId64,
754 n, (int64) len * 8 - 1)));
755
756 /* n/8 is now known < len, so safe to cast to int */
757 byteNo = (int) (n / 8);
758 bitNo = (int) (n % 8);
759
760 /*
761 * sanity check!
762 */
763 if (newBit != 0 && newBit != 1)
766 errmsg("new bit must be 0 or 1")));
767
768 /*
769 * Update the byte.
770 */
771 oldByte = ((unsigned char *) VARDATA(res))[byteNo];
772
773 if (newBit == 0)
774 newByte = oldByte & (~(1 << bitNo));
775 else
776 newByte = oldByte | (1 << bitNo);
777
778 ((unsigned char *) VARDATA(res))[byteNo] = newByte;
779
781}
782
783/*
784 * Return reversed bytea
785 */
786Datum
788{
790 const char *p = VARDATA_ANY(v);
791 int len = VARSIZE_ANY_EXHDR(v);
792 const char *endp = p + len;
793 bytea *result = palloc(len + VARHDRSZ);
794 char *dst = (char *) VARDATA(result) + len;
795
796 SET_VARSIZE(result, len + VARHDRSZ);
797
798 while (p < endp)
799 *(--dst) = *p++;
800
801 PG_RETURN_BYTEA_P(result);
802}
803
804
805/*****************************************************************************
806 * Comparison Functions used for bytea
807 *
808 * Note: btree indexes need these routines not to leak memory; therefore,
809 * be careful to free working copies of toasted datums. Most places don't
810 * need to be so careful.
811 *****************************************************************************/
812
813Datum
815{
818 bool result;
819 Size len1,
820 len2;
821
822 /*
823 * We can use a fast path for unequal lengths, which might save us from
824 * having to detoast one or both values.
825 */
828 if (len1 != len2)
829 result = false;
830 else
831 {
834
836 len1 - VARHDRSZ) == 0);
837
840 }
841
842 PG_RETURN_BOOL(result);
843}
844
845Datum
847{
850 bool result;
851 Size len1,
852 len2;
853
854 /*
855 * We can use a fast path for unequal lengths, which might save us from
856 * having to detoast one or both values.
857 */
860 if (len1 != len2)
861 result = true;
862 else
863 {
866
868 len1 - VARHDRSZ) != 0);
869
872 }
873
874 PG_RETURN_BOOL(result);
875}
876
877Datum
879{
882 int len1,
883 len2;
884 int cmp;
885
886 len1 = VARSIZE_ANY_EXHDR(arg1);
887 len2 = VARSIZE_ANY_EXHDR(arg2);
888
889 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
890
893
894 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
895}
896
897Datum
899{
902 int len1,
903 len2;
904 int cmp;
905
906 len1 = VARSIZE_ANY_EXHDR(arg1);
907 len2 = VARSIZE_ANY_EXHDR(arg2);
908
909 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
910
913
914 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
915}
916
917Datum
919{
922 int len1,
923 len2;
924 int cmp;
925
926 len1 = VARSIZE_ANY_EXHDR(arg1);
927 len2 = VARSIZE_ANY_EXHDR(arg2);
928
929 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
930
933
934 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
935}
936
937Datum
939{
942 int len1,
943 len2;
944 int cmp;
945
946 len1 = VARSIZE_ANY_EXHDR(arg1);
947 len2 = VARSIZE_ANY_EXHDR(arg2);
948
949 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
950
953
954 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
955}
956
957Datum
959{
962 int len1,
963 len2;
964 int cmp;
965
966 len1 = VARSIZE_ANY_EXHDR(arg1);
967 len2 = VARSIZE_ANY_EXHDR(arg2);
968
969 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
970 if ((cmp == 0) && (len1 != len2))
971 cmp = (len1 < len2) ? -1 : 1;
972
975
977}
978
979Datum
981{
984 bytea *result;
985 int len1,
986 len2;
987 int cmp;
988
989 len1 = VARSIZE_ANY_EXHDR(arg1);
990 len2 = VARSIZE_ANY_EXHDR(arg2);
991
992 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
993 result = ((cmp > 0) || ((cmp == 0) && (len1 > len2)) ? arg1 : arg2);
994
995 PG_RETURN_BYTEA_P(result);
996}
997
998Datum
1000{
1003 bytea *result;
1004 int len1,
1005 len2;
1006 int cmp;
1007
1008 len1 = VARSIZE_ANY_EXHDR(arg1);
1009 len2 = VARSIZE_ANY_EXHDR(arg2);
1010
1011 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
1012 result = ((cmp < 0) || ((cmp == 0) && (len1 < len2)) ? arg1 : arg2);
1013
1014 PG_RETURN_BYTEA_P(result);
1015}
1016
1017/*
1018 * sortsupport comparison func
1019 */
1020static int
1022{
1025 char *a1p,
1026 *a2p;
1027 int len1,
1028 len2,
1029 result;
1030
1031 a1p = VARDATA_ANY(arg1);
1032 a2p = VARDATA_ANY(arg2);
1033
1034 len1 = VARSIZE_ANY_EXHDR(arg1);
1035 len2 = VARSIZE_ANY_EXHDR(arg2);
1036
1037 result = memcmp(a1p, a2p, Min(len1, len2));
1038 if ((result == 0) && (len1 != len2))
1039 result = (len1 < len2) ? -1 : 1;
1040
1041 /* We can't afford to leak memory here. */
1042 if (PointerGetDatum(arg1) != x)
1043 pfree(arg1);
1044 if (PointerGetDatum(arg2) != y)
1045 pfree(arg2);
1046
1047 return result;
1048}
1049
1050/*
1051 * Conversion routine for sortsupport. Converts original to abbreviated key
1052 * representation. Our encoding strategy is simple -- pack the first 8 bytes
1053 * of the bytea data into a Datum (on little-endian machines, the bytes are
1054 * stored in reverse order), and treat it as an unsigned integer.
1055 */
1056static Datum
1058{
1059 const size_t max_prefix_bytes = sizeof(Datum);
1061 bytea *authoritative = DatumGetByteaPP(original);
1063 Datum res;
1064 char *pres;
1065 int len;
1066 uint32 hash;
1067
1068 pres = (char *) &res;
1069
1070 /* memset(), so any non-overwritten bytes are NUL */
1073
1074 /*
1075 * Short byteas will have terminating NUL bytes in the abbreviated datum.
1076 * Abbreviated comparison need not make a distinction between these NUL
1077 * bytes, and NUL bytes representing actual NULs in the authoritative
1078 * representation.
1079 *
1080 * Hopefully a comparison at or past one abbreviated key's terminating NUL
1081 * byte will resolve the comparison without consulting the authoritative
1082 * representation; specifically, some later non-NUL byte in the longer
1083 * bytea can resolve the comparison against a subsequent terminating NUL
1084 * in the shorter bytea. There will usually be what is effectively a
1085 * "length-wise" resolution there and then.
1086 *
1087 * If that doesn't work out -- if all bytes in the longer bytea positioned
1088 * at or past the offset of the smaller bytea (first) terminating NUL are
1089 * actually representative of NUL bytes in the authoritative binary bytea
1090 * (perhaps with some *terminating* NUL bytes towards the end of the
1091 * longer bytea iff it happens to still be small) -- then an authoritative
1092 * tie-breaker will happen, and do the right thing: explicitly consider
1093 * bytea length.
1094 */
1096
1097 /*
1098 * Maintain approximate cardinality of both abbreviated keys and original,
1099 * authoritative keys using HyperLogLog. Used as cheap insurance against
1100 * the worst case, where we do many string abbreviations for no saving in
1101 * full memcmp()-based comparisons. These statistics are used by
1102 * bytea_abbrev_abort().
1103 *
1104 * First, Hash key proper, or a significant fraction of it. Mix in length
1105 * in order to compensate for cases where differences are past
1106 * PG_CACHE_LINE_SIZE bytes, so as to limit the overhead of hashing.
1107 */
1108 hash = DatumGetUInt32(hash_any((unsigned char *) authoritative_data,
1110
1111 if (len > PG_CACHE_LINE_SIZE)
1113
1114 addHyperLogLog(&bss->full_card, hash);
1115
1116 /* Hash abbreviated key */
1117 {
1118 uint32 tmp;
1119
1120 tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
1122 }
1123
1124 addHyperLogLog(&bss->abbr_card, hash);
1125
1126 /*
1127 * Byteswap on little-endian machines.
1128 *
1129 * This is needed so that ssup_datum_unsigned_cmp() works correctly on all
1130 * platforms.
1131 */
1132 res = DatumBigEndianToNative(res);
1133
1134 /* Don't leak memory here */
1135 if (PointerGetDatum(authoritative) != original)
1137
1138 return res;
1139}
1140
1141/*
1142 * Callback for estimating effectiveness of abbreviated key optimization, using
1143 * heuristic rules. Returns value indicating if the abbreviation optimization
1144 * should be aborted, based on its projected effectiveness.
1145 *
1146 * This is based on varstr_abbrev_abort(), but some comments have been elided
1147 * for brevity. See there for more details.
1148 */
1149static bool
1150bytea_abbrev_abort(int memtupcount, SortSupport ssup)
1151{
1153 double abbrev_distinct,
1155
1156 Assert(ssup->abbreviate);
1157
1158 /* Have a little patience */
1159 if (memtupcount < 100)
1160 return false;
1161
1163 key_distinct = estimateHyperLogLog(&bss->full_card);
1164
1165 /*
1166 * Clamp cardinality estimates to at least one distinct value. While
1167 * NULLs are generally disregarded, if only NULL values were seen so far,
1168 * that might misrepresent costs if we failed to clamp.
1169 */
1170 if (abbrev_distinct < 1.0)
1171 abbrev_distinct = 1.0;
1172
1173 if (key_distinct < 1.0)
1174 key_distinct = 1.0;
1175
1176 if (trace_sort)
1177 {
1178 double norm_abbrev_card = abbrev_distinct / (double) memtupcount;
1179
1180 elog(LOG, "bytea_abbrev: abbrev_distinct after %d: %f "
1181 "(key_distinct: %f, norm_abbrev_card: %f, prop_card: %f)",
1183 bss->prop_card);
1184 }
1185
1186 /*
1187 * If the number of distinct abbreviated keys approximately matches the
1188 * number of distinct original keys, continue with abbreviation.
1189 */
1190 if (abbrev_distinct > key_distinct * bss->prop_card)
1191 {
1192 /*
1193 * Decay required cardinality aggressively after 10,000 tuples.
1194 */
1195 if (memtupcount > 10000)
1196 bss->prop_card *= 0.65;
1197
1198 return false;
1199 }
1200
1201 /*
1202 * Abort abbreviation strategy.
1203 */
1204 if (trace_sort)
1205 elog(LOG, "bytea_abbrev: aborted abbreviation at %d "
1206 "(abbrev_distinct: %f, key_distinct: %f, prop_card: %f)",
1207 memtupcount, abbrev_distinct, key_distinct, bss->prop_card);
1208
1209 return true;
1210}
1211
1212Datum
1214{
1216 MemoryContext oldcontext;
1217
1218 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1219
1220 ssup->comparator = byteafastcmp;
1221
1222 /*
1223 * Set up abbreviation support if requested.
1224 */
1225 if (ssup->abbreviate)
1226 {
1228
1230 bss->abbreviate = true;
1231 bss->prop_card = 0.20;
1232 initHyperLogLog(&bss->abbr_card, 10);
1233 initHyperLogLog(&bss->full_card, 10);
1234
1235 ssup->ssup_extra = bss;
1236 ssup->abbrev_full_comparator = ssup->comparator;
1240 }
1241
1242 MemoryContextSwitchTo(oldcontext);
1243
1245}
1246
1247/* Cast bytea -> int2 */
1248Datum
1250{
1251 bytea *v = PG_GETARG_BYTEA_PP(0);
1252 int len = VARSIZE_ANY_EXHDR(v);
1253 uint16 result;
1254
1255 /* Check that the byte array is not too long */
1256 if (len > sizeof(result))
1257 ereport(ERROR,
1259 errmsg("smallint out of range"));
1260
1261 /* Convert it to an integer; most significant bytes come first */
1262 result = 0;
1263 for (int i = 0; i < len; i++)
1264 {
1265 result <<= BITS_PER_BYTE;
1266 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1267 }
1268
1269 PG_RETURN_INT16(result);
1270}
1271
1272/* Cast bytea -> int4 */
1273Datum
1275{
1276 bytea *v = PG_GETARG_BYTEA_PP(0);
1277 int len = VARSIZE_ANY_EXHDR(v);
1278 uint32 result;
1279
1280 /* Check that the byte array is not too long */
1281 if (len > sizeof(result))
1282 ereport(ERROR,
1284 errmsg("integer out of range"));
1285
1286 /* Convert it to an integer; most significant bytes come first */
1287 result = 0;
1288 for (int i = 0; i < len; i++)
1289 {
1290 result <<= BITS_PER_BYTE;
1291 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1292 }
1293
1294 PG_RETURN_INT32(result);
1295}
1296
1297/* Cast bytea -> int8 */
1298Datum
1300{
1301 bytea *v = PG_GETARG_BYTEA_PP(0);
1302 int len = VARSIZE_ANY_EXHDR(v);
1303 uint64 result;
1304
1305 /* Check that the byte array is not too long */
1306 if (len > sizeof(result))
1307 ereport(ERROR,
1309 errmsg("bigint out of range"));
1310
1311 /* Convert it to an integer; most significant bytes come first */
1312 result = 0;
1313 for (int i = 0; i < len; i++)
1314 {
1315 result <<= BITS_PER_BYTE;
1316 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1317 }
1318
1319 PG_RETURN_INT64(result);
1320}
1321
1322/* Cast int2 -> bytea; can just use int2send() */
1323Datum
1325{
1326 return int2send(fcinfo);
1327}
1328
1329/* Cast int4 -> bytea; can just use int4send() */
1330Datum
1332{
1333 return int4send(fcinfo);
1334}
1335
1336/* Cast int8 -> bytea; can just use int8send() */
1337Datum
1339{
1340 return int8send(fcinfo);
1341}
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:997
#define Max(x, y)
Definition c.h:991
#define VARHDRSZ
Definition c.h:711
#define Assert(condition)
Definition c.h:873
int64_t int64
Definition c.h:543
int32_t int32
Definition c.h:542
uint64_t uint64
Definition c.h:547
uint16_t uint16
Definition c.h:545
uint32_t uint32
Definition c.h:546
size_t Size
Definition c.h:619
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:350
#define PG_FREE_IF_COPY(ptr, n)
Definition fmgr.h:260
#define DatumGetByteaPSlice(X, m, n)
Definition fmgr.h:304
#define PG_GETARG_BYTEA_PP(n)
Definition fmgr.h:309
#define PG_RETURN_BYTEA_P(x)
Definition fmgr.h:373
#define DatumGetByteaPP(X)
Definition fmgr.h:292
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define PG_RETURN_CSTRING(x)
Definition fmgr.h:364
#define PG_ARGISNULL(n)
Definition fmgr.h:209
#define PG_RETURN_INT64(x)
Definition fmgr.h:370
#define PG_GETARG_DATUM(n)
Definition fmgr.h:268
#define PG_GETARG_CSTRING(n)
Definition fmgr.h:278
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_INT64(n)
Definition fmgr.h:284
#define PG_RETURN_INT16(x)
Definition fmgr.h:357
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_GETARG_BYTEA_P_COPY(n)
Definition fmgr.h:315
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition fmgr.h:360
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
const char * str
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
Definition hyperloglog.c:66
double estimateHyperLogLog(hyperLogLogState *cState)
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
long val
Definition informix.c:689
static struct @172 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:1616
void * palloc(Size size)
Definition mcxt.c:1387
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)
#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]
static uint32 DatumGetUInt32(Datum X)
Definition postgres.h:232
static uint64 DatumGetUInt64(Datum X)
Definition postgres.h:433
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
uint64_t Datum
Definition postgres.h:70
void pq_copymsgbytes(StringInfo msg, void *buf, int datalen)
Definition pqformat.c:527
static int fb(int x)
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
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
Definition nodes.h:135
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
MemoryContext ssup_cxt
Definition sortsupport.h:66
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
Definition c.h:706
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition tuplesort.c:3122
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

◆ VAL

#define VAL (   CH)    ((CH) - '0')

Definition at line 191 of file bytea.c.

Function Documentation

◆ bytea_abbrev_abort()

static bool bytea_abbrev_abort ( int  memtupcount,
SortSupport  ssup 
)
static

Definition at line 1151 of file bytea.c.

1152{
1154 double abbrev_distinct,
1156
1157 Assert(ssup->abbreviate);
1158
1159 /* Have a little patience */
1160 if (memtupcount < 100)
1161 return false;
1162
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)",
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}

References SortSupportData::abbreviate, Assert, elog, estimateHyperLogLog(), fb(), LOG, SortSupportData::ssup_extra, and trace_sort.

Referenced by bytea_sortsupport().

◆ bytea_abbrev_convert()

static Datum bytea_abbrev_convert ( Datum  original,
SortSupport  ssup 
)
static

Definition at line 1058 of file bytea.c.

1059{
1060 const size_t max_prefix_bytes = sizeof(Datum);
1062 bytea *authoritative = DatumGetByteaPP(original);
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 */
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 */
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
1115 addHyperLogLog(&bss->full_card, hash);
1116
1117 /* Hash abbreviated key */
1118 {
1119 uint32 tmp;
1120
1121 tmp = DatumGetUInt32(res) ^ (uint32) (DatumGetUInt64(res) >> 32);
1123 }
1124
1125 addHyperLogLog(&bss->abbr_card, hash);
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)
1138
1139 return res;
1140}

References addHyperLogLog(), DatumBigEndianToNative, DatumGetByteaPP, DatumGetUInt32(), DatumGetUInt64(), fb(), hash(), hash_any(), hash_uint32(), len, Min, pfree(), PG_CACHE_LINE_SIZE, PointerGetDatum(), SortSupportData::ssup_extra, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by bytea_sortsupport().

◆ bytea_bit_count()

◆ bytea_catenate()

static bytea * bytea_catenate ( bytea t1,
bytea t2 
)
static

Definition at line 61 of file bytea.c.

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}

References fb(), len, palloc(), SET_VARSIZE(), VARDATA(), VARDATA_ANY(), VARHDRSZ, and VARSIZE_ANY_EXHDR().

Referenced by bytea_overlay(), and byteacat().

◆ bytea_int2()

Datum bytea_int2 ( PG_FUNCTION_ARGS  )

Definition at line 1250 of file bytea.c.

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,
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}

References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, fb(), i, len, PG_GETARG_BYTEA_PP, PG_RETURN_INT16, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytea_int4()

Datum bytea_int4 ( PG_FUNCTION_ARGS  )

Definition at line 1275 of file bytea.c.

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,
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}

References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, fb(), i, len, PG_GETARG_BYTEA_PP, PG_RETURN_INT32, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytea_int8()

Datum bytea_int8 ( PG_FUNCTION_ARGS  )

Definition at line 1300 of file bytea.c.

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,
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}

References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, fb(), i, len, PG_GETARG_BYTEA_PP, PG_RETURN_INT64, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytea_larger()

Datum bytea_larger ( PG_FUNCTION_ARGS  )

Definition at line 981 of file bytea.c.

982{
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}

References cmp(), fb(), Min, PG_GETARG_BYTEA_PP, PG_RETURN_BYTEA_P, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytea_overlay()

static bytea * bytea_overlay ( bytea t1,
bytea t2,
int  sp,
int  sl 
)
static

Definition at line 158 of file bytea.c.

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)
173 errmsg("negative substring length not allowed")));
177 errmsg("integer out of range")));
178
179 s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
181 result = bytea_catenate(s1, t2);
182 result = bytea_catenate(result, s2);
183
184 return result;
185}

References bytea_catenate(), bytea_substring(), ereport, errcode(), errmsg(), ERROR, fb(), pg_add_s32_overflow(), PointerGetDatum(), s1, and s2.

Referenced by byteaoverlay(), and byteaoverlay_no_len().

◆ bytea_reverse()

Datum bytea_reverse ( PG_FUNCTION_ARGS  )

Definition at line 788 of file bytea.c.

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}

References fb(), len, palloc(), PG_GETARG_BYTEA_PP, PG_RETURN_BYTEA_P, SET_VARSIZE(), VARDATA(), VARDATA_ANY(), VARHDRSZ, and VARSIZE_ANY_EXHDR().

◆ bytea_smaller()

Datum bytea_smaller ( PG_FUNCTION_ARGS  )

Definition at line 1000 of file bytea.c.

1001{
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}

References cmp(), fb(), Min, PG_GETARG_BYTEA_PP, PG_RETURN_BYTEA_P, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1214 of file bytea.c.

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 {
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}

References SortSupportData::abbrev_abort, SortSupportData::abbrev_converter, SortSupportData::abbrev_full_comparator, SortSupportData::abbreviate, bytea_abbrev_abort(), bytea_abbrev_convert(), byteafastcmp(), SortSupportData::comparator, fb(), initHyperLogLog(), MemoryContextSwitchTo(), palloc_object, PG_GETARG_POINTER, PG_RETURN_VOID, SortSupportData::ssup_cxt, ssup_datum_unsigned_cmp(), and SortSupportData::ssup_extra.

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 454 of file bytea.c.

455{
457
458 /* cannot be called directly because of internal-type argument */
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);
471 memcpy(VARDATA(result), &state->data[state->cursor], strippedlen);
472 PG_RETURN_BYTEA_P(result);
473 }
474 else
476}

References AggCheckCallContext(), Assert, fb(), palloc(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_BYTEA_P, PG_RETURN_NULL, SET_VARSIZE(), VARDATA(), and VARHDRSZ.

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 385 of file bytea.c.

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}

References AggCheckCallContext(), appendBinaryStringInfo(), elog, ERROR, fb(), makeStringInfo(), MemoryContextSwitchTo(), PG_ARGISNULL, PG_GETARG_BYTEA_PP, PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_POINTER, value, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 555 of file bytea.c.

556{
560 false));
561}

References bytea_substring(), PG_GETARG_DATUM, PG_GETARG_INT32, and PG_RETURN_BYTEA_P.

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 569 of file bytea.c.

570{
573 -1,
574 true));
575}

References bytea_substring(), PG_GETARG_DATUM, PG_GETARG_INT32, and PG_RETURN_BYTEA_P.

◆ bytea_substring()

static bytea * bytea_substring ( Datum  str,
int  S,
int  L,
bool  length_not_specified 
)
static

Definition at line 98 of file bytea.c.

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
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 */
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}

References DatumGetByteaPSlice, ereport, errcode(), errmsg(), ERROR, fb(), Max, pg_add_s32_overflow(), PG_STR_GET_BYTEA, S, and str.

Referenced by bytea_overlay(), bytea_substr(), and bytea_substr_no_len().

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 501 of file bytea.c.

References bytea_catenate(), fb(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

Definition at line 959 of file bytea.c.

960{
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
976
978}

References cmp(), fb(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_INT32, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by gbt_bit_ssup_cmp(), gbt_bitcmp(), gbt_bytea_ssup_cmp(), and gbt_byteacmp().

◆ byteaeq()

Datum byteaeq ( PG_FUNCTION_ARGS  )

Definition at line 815 of file bytea.c.

816{
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 */
829 if (len1 != len2)
830 result = false;
831 else
832 {
835
837 len1 - VARHDRSZ) == 0);
838
841 }
842
843 PG_RETURN_BOOL(result);
844}

References DatumGetByteaPP, fb(), PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_RETURN_BOOL, toast_raw_datum_size(), VARDATA_ANY(), and VARHDRSZ.

Referenced by gbt_byteaeq().

◆ byteafastcmp()

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

Definition at line 1022 of file bytea.c.

1023{
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}

References DatumGetByteaPP, fb(), Min, pfree(), PointerGetDatum(), VARDATA_ANY(), VARSIZE_ANY_EXHDR(), x, and y.

Referenced by bytea_sortsupport().

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

Definition at line 939 of file bytea.c.

940{
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
954
955 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
956}

References cmp(), fb(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by gbt_byteage().

◆ byteaGetBit()

Datum byteaGetBit ( PG_FUNCTION_ARGS  )

Definition at line 668 of file bytea.c.

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)
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}

References ereport, errcode(), errmsg(), ERROR, fb(), len, PG_GETARG_BYTEA_PP, PG_GETARG_INT64, PG_RETURN_INT32, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

Definition at line 639 of file bytea.c.

640{
642 int32 n = PG_GETARG_INT32(1);
643 int len;
644 int byte;
645
647
648 if (n < 0 || n >= len)
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}

References ereport, errcode(), errmsg(), ERROR, fb(), len, PG_GETARG_BYTEA_PP, PG_GETARG_INT32, PG_RETURN_INT32, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

Definition at line 919 of file bytea.c.

920{
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
934
935 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
936}

References cmp(), fb(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by gbt_byteagt().

◆ byteain()

Datum byteain ( PG_FUNCTION_ARGS  )

Definition at line 201 of file bytea.c.

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,
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}

References ereturn, errcode(), errmsg(), fb(), hex_decode_safe(), len, palloc(), PG_GETARG_CSTRING, PG_RETURN_BYTEA_P, SET_VARSIZE(), VAL, VARDATA(), and VARHDRSZ.

Referenced by CreateTriggerFiringOn(), and string_to_datum().

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

Definition at line 899 of file bytea.c.

900{
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
914
915 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
916}

References cmp(), fb(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by gbt_byteale().

◆ bytealt()

Datum bytealt ( PG_FUNCTION_ARGS  )

Definition at line 879 of file bytea.c.

880{
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
894
895 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
896}

References cmp(), fb(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by gbt_bytealt().

◆ byteane()

Datum byteane ( PG_FUNCTION_ARGS  )

Definition at line 847 of file bytea.c.

848{
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 */
861 if (len1 != len2)
862 result = true;
863 else
864 {
867
869 len1 - VARHDRSZ) != 0);
870
873 }
874
875 PG_RETURN_BOOL(result);
876}

References DatumGetByteaPP, fb(), PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_RETURN_BOOL, toast_raw_datum_size(), VARDATA_ANY(), and VARHDRSZ.

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 485 of file bytea.c.

486{
488
489 /* We need not detoast the input at all */
491}

References PG_GETARG_DATUM, PG_RETURN_INT32, str, toast_raw_datum_size(), and VARHDRSZ.

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 275 of file bytea.c.

276{
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';
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 */
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)
316 errmsg_internal("result of bytea output conversion is too large")));
317 rp = result = (char *) palloc(len);
318
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}

References bytea_output, BYTEA_OUTPUT_ESCAPE, BYTEA_OUTPUT_HEX, DIG, elog, ereport, errcode(), errmsg_internal(), ERROR, fb(), hex_encode(), i, len, MaxAllocSize, palloc(), PG_GETARG_BYTEA_PP, PG_RETURN_CSTRING, val, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by pg_mcv_list_out().

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 517 of file bytea.c.

518{
521 int sp = PG_GETARG_INT32(2); /* substring start position */
522 int sl = PG_GETARG_INT32(3); /* substring length */
523
525}

References bytea_overlay(), fb(), PG_GETARG_BYTEA_PP, PG_GETARG_INT32, and PG_RETURN_BYTEA_P.

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 528 of file bytea.c.

529{
532 int sp = PG_GETARG_INT32(2); /* substring start position */
533 int sl;
534
535 sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
537}

References bytea_overlay(), fb(), PG_GETARG_BYTEA_PP, PG_GETARG_INT32, PG_RETURN_BYTEA_P, and VARSIZE_ANY_EXHDR().

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 595 of file bytea.c.

596{
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}

References fb(), PG_GETARG_BYTEA_PP, PG_RETURN_INT32, px(), VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

Definition at line 358 of file bytea.c.

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}

References buf, palloc(), PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_copymsgbytes(), SET_VARSIZE(), VARDATA(), and VARHDRSZ.

◆ byteasend()

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 738 of file bytea.c.

739{
741 int64 n = PG_GETARG_INT64(1);
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)
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)
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}

References ereport, errcode(), errmsg(), ERROR, fb(), len, PG_GETARG_BYTEA_P_COPY, PG_GETARG_INT32, PG_GETARG_INT64, PG_RETURN_BYTEA_P, VARDATA(), VARHDRSZ, and VARSIZE().

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

Definition at line 706 of file bytea.c.

707{
709 int32 n = PG_GETARG_INT32(1);
711 int len;
712
713 len = VARSIZE(res) - VARHDRSZ;
714
715 if (n < 0 || n >= len)
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}

References ereport, errcode(), errmsg(), ERROR, fb(), len, PG_GETARG_BYTEA_P_COPY, PG_GETARG_INT32, PG_RETURN_BYTEA_P, VARDATA(), VARHDRSZ, and VARSIZE().

◆ int2_bytea()

Datum int2_bytea ( PG_FUNCTION_ARGS  )

Definition at line 1325 of file bytea.c.

1326{
1327 return int2send(fcinfo);
1328}

References int2send().

◆ int4_bytea()

Datum int4_bytea ( PG_FUNCTION_ARGS  )

Definition at line 1332 of file bytea.c.

1333{
1334 return int4send(fcinfo);
1335}

References int4send().

◆ int8_bytea()

Datum int8_bytea ( PG_FUNCTION_ARGS  )

Definition at line 1339 of file bytea.c.

1340{
1341 return int8send(fcinfo);
1342}

References int8send().

Variable Documentation

◆ bytea_output

int bytea_output = BYTEA_OUTPUT_HEX

Definition at line 34 of file bytea.c.

Referenced by byteaout().