Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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 "catalog/pg_collation_d.h"
19#include "catalog/pg_type_d.h"
20#include "common/int.h"
21#include "fmgr.h"
22#include "libpq/pqformat.h"
23#include "port/pg_bitutils.h"
24#include "utils/builtins.h"
25#include "utils/bytea.h"
26#include "utils/fmgrprotos.h"
27#include "utils/memutils.h"
28#include "utils/sortsupport.h"
29#include "utils/varlena.h"
30#include "varatt.h"
31
32/* GUC variable */
34
35static bytea *bytea_catenate(bytea *t1, bytea *t2);
36static bytea *bytea_substring(Datum str, int S, int L,
37 bool length_not_specified);
38static bytea *bytea_overlay(bytea *t1, bytea *t2, int sp, int sl);
39
40/*
41 * bytea_catenate
42 * Guts of byteacat(), broken out so it can be used by other functions
43 *
44 * Arguments can be in short-header form, but not compressed or out-of-line
45 */
46static bytea *
48{
49 bytea *result;
50 int len1,
51 len2,
52 len;
53 char *ptr;
54
55 len1 = VARSIZE_ANY_EXHDR(t1);
56 len2 = VARSIZE_ANY_EXHDR(t2);
57
58 /* paranoia ... probably should throw error instead? */
59 if (len1 < 0)
60 len1 = 0;
61 if (len2 < 0)
62 len2 = 0;
63
64 len = len1 + len2 + VARHDRSZ;
65 result = (bytea *) palloc(len);
66
67 /* Set size of result string... */
68 SET_VARSIZE(result, len);
69
70 /* Fill data field of result string... */
71 ptr = VARDATA(result);
72 if (len1 > 0)
73 memcpy(ptr, VARDATA_ANY(t1), len1);
74 if (len2 > 0)
75 memcpy(ptr + len1, VARDATA_ANY(t2), len2);
76
77 return result;
78}
79
80#define PG_STR_GET_BYTEA(str_) \
81 DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
82
83static bytea *
85 int S,
86 int L,
87 bool length_not_specified)
88{
89 int32 S1; /* adjusted start position */
90 int32 L1; /* adjusted substring length */
91 int32 E; /* end position */
92
93 /*
94 * The logic here should generally match text_substring().
95 */
96 S1 = Max(S, 1);
97
98 if (length_not_specified)
99 {
100 /*
101 * Not passed a length - DatumGetByteaPSlice() grabs everything to the
102 * end of the string if we pass it a negative value for length.
103 */
104 L1 = -1;
105 }
106 else if (L < 0)
107 {
108 /* SQL99 says to throw an error for E < S, i.e., negative length */
110 (errcode(ERRCODE_SUBSTRING_ERROR),
111 errmsg("negative substring length not allowed")));
112 L1 = -1; /* silence stupider compilers */
113 }
114 else if (pg_add_s32_overflow(S, L, &E))
115 {
116 /*
117 * L could be large enough for S + L to overflow, in which case the
118 * substring must run to end of string.
119 */
120 L1 = -1;
121 }
122 else
123 {
124 /*
125 * A zero or negative value for the end position can happen if the
126 * start was negative or one. SQL99 says to return a zero-length
127 * string.
128 */
129 if (E < 1)
130 return PG_STR_GET_BYTEA("");
131
132 L1 = E - S1;
133 }
134
135 /*
136 * If the start position is past the end of the string, SQL99 says to
137 * return a zero-length string -- DatumGetByteaPSlice() will do that for
138 * us. We need only convert S1 to zero-based starting position.
139 */
140 return DatumGetByteaPSlice(str, S1 - 1, L1);
141}
142
143static bytea *
144bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
145{
146 bytea *result;
147 bytea *s1;
148 bytea *s2;
149 int sp_pl_sl;
150
151 /*
152 * Check for possible integer-overflow cases. For negative sp, throw a
153 * "substring length" error because that's what should be expected
154 * according to the spec's definition of OVERLAY().
155 */
156 if (sp <= 0)
158 (errcode(ERRCODE_SUBSTRING_ERROR),
159 errmsg("negative substring length not allowed")));
160 if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
162 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
163 errmsg("integer out of range")));
164
165 s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
166 s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
167 result = bytea_catenate(s1, t2);
168 result = bytea_catenate(result, s2);
169
170 return result;
171}
172
173/*****************************************************************************
174 * USER I/O ROUTINES *
175 *****************************************************************************/
176
177#define VAL(CH) ((CH) - '0')
178#define DIG(VAL) ((VAL) + '0')
179
180/*
181 * byteain - converts from printable representation of byte array
182 *
183 * Non-printable characters must be passed as '\nnn' (octal) and are
184 * converted to internal form. '\' must be passed as '\\'.
185 */
186Datum
188{
189 char *inputText = PG_GETARG_CSTRING(0);
190 Node *escontext = fcinfo->context;
191 size_t len = strlen(inputText);
192 size_t bc;
193 char *tp;
194 char *rp;
195 bytea *result;
196
197 /* Recognize hex input */
198 if (inputText[0] == '\\' && inputText[1] == 'x')
199 {
200 bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */
201 result = palloc(bc);
202 bc = hex_decode_safe(inputText + 2, len - 2, VARDATA(result),
203 escontext);
204 SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
205
206 PG_RETURN_BYTEA_P(result);
207 }
208
209 /* Else, it's the traditional escaped style */
210 result = (bytea *) palloc(len + VARHDRSZ); /* maximum possible length */
211
212 tp = inputText;
213 rp = VARDATA(result);
214 while (*tp != '\0')
215 {
216 if (tp[0] != '\\')
217 *rp++ = *tp++;
218 else if ((tp[1] >= '0' && tp[1] <= '3') &&
219 (tp[2] >= '0' && tp[2] <= '7') &&
220 (tp[3] >= '0' && tp[3] <= '7'))
221 {
222 int v;
223
224 v = VAL(tp[1]);
225 v <<= 3;
226 v += VAL(tp[2]);
227 v <<= 3;
228 *rp++ = v + VAL(tp[3]);
229
230 tp += 4;
231 }
232 else if (tp[1] == '\\')
233 {
234 *rp++ = '\\';
235 tp += 2;
236 }
237 else
238 {
239 /*
240 * one backslash, not followed by another or ### valid octal
241 */
242 ereturn(escontext, (Datum) 0,
243 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
244 errmsg("invalid input syntax for type %s", "bytea")));
245 }
246 }
247
248 bc = rp - VARDATA(result); /* actual length */
249 SET_VARSIZE(result, bc + VARHDRSZ);
250
251 PG_RETURN_BYTEA_P(result);
252}
253
254/*
255 * byteaout - converts to printable representation of byte array
256 *
257 * In the traditional escaped format, non-printable characters are
258 * printed as '\nnn' (octal) and '\' as '\\'.
259 */
260Datum
262{
263 bytea *vlena = PG_GETARG_BYTEA_PP(0);
264 char *result;
265 char *rp;
266
268 {
269 /* Print hex format */
270 rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
271 *rp++ = '\\';
272 *rp++ = 'x';
273 rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
274 }
276 {
277 /* Print traditional escaped format */
278 char *vp;
279 uint64 len;
280 int i;
281
282 len = 1; /* empty string has 1 char */
283 vp = VARDATA_ANY(vlena);
284 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
285 {
286 if (*vp == '\\')
287 len += 2;
288 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
289 len += 4;
290 else
291 len++;
292 }
293
294 /*
295 * In principle len can't overflow uint32 if the input fit in 1GB, but
296 * for safety let's check rather than relying on palloc's internal
297 * check.
298 */
299 if (len > MaxAllocSize)
301 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
302 errmsg_internal("result of bytea output conversion is too large")));
303 rp = result = (char *) palloc(len);
304
305 vp = VARDATA_ANY(vlena);
306 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
307 {
308 if (*vp == '\\')
309 {
310 *rp++ = '\\';
311 *rp++ = '\\';
312 }
313 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
314 {
315 int val; /* holds unprintable chars */
316
317 val = *vp;
318 rp[0] = '\\';
319 rp[3] = DIG(val & 07);
320 val >>= 3;
321 rp[2] = DIG(val & 07);
322 val >>= 3;
323 rp[1] = DIG(val & 03);
324 rp += 4;
325 }
326 else
327 *rp++ = *vp;
328 }
329 }
330 else
331 {
332 elog(ERROR, "unrecognized \"bytea_output\" setting: %d",
334 rp = result = NULL; /* keep compiler quiet */
335 }
336 *rp = '\0';
337 PG_RETURN_CSTRING(result);
338}
339
340/*
341 * bytearecv - converts external binary format to bytea
342 */
343Datum
345{
347 bytea *result;
348 int nbytes;
349
350 nbytes = buf->len - buf->cursor;
351 result = (bytea *) palloc(nbytes + VARHDRSZ);
352 SET_VARSIZE(result, nbytes + VARHDRSZ);
353 pq_copymsgbytes(buf, VARDATA(result), nbytes);
354 PG_RETURN_BYTEA_P(result);
355}
356
357/*
358 * byteasend - converts bytea to binary format
359 *
360 * This is a special case: just copy the input...
361 */
362Datum
364{
365 bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
366
367 PG_RETURN_BYTEA_P(vlena);
368}
369
370Datum
372{
374
376
377 /* Append the value unless null, preceding it with the delimiter. */
378 if (!PG_ARGISNULL(1))
379 {
381 bool isfirst = false;
382
383 /*
384 * You might think we can just throw away the first delimiter, however
385 * we must keep it as we may be a parallel worker doing partial
386 * aggregation building a state to send to the main process. We need
387 * to keep the delimiter of every aggregation so that the combine
388 * function can properly join up the strings of two separately
389 * partially aggregated results. The first delimiter is only stripped
390 * off in the final function. To know how much to strip off the front
391 * of the string, we store the length of the first delimiter in the
392 * StringInfo's cursor field, which we don't otherwise need here.
393 */
394 if (state == NULL)
395 {
396 MemoryContext aggcontext;
397 MemoryContext oldcontext;
398
399 if (!AggCheckCallContext(fcinfo, &aggcontext))
400 {
401 /* cannot be called directly because of internal-type argument */
402 elog(ERROR, "bytea_string_agg_transfn called in non-aggregate context");
403 }
404
405 /*
406 * Create state in aggregate context. It'll stay there across
407 * subsequent calls.
408 */
409 oldcontext = MemoryContextSwitchTo(aggcontext);
411 MemoryContextSwitchTo(oldcontext);
412
413 isfirst = true;
414 }
415
416 if (!PG_ARGISNULL(2))
417 {
418 bytea *delim = PG_GETARG_BYTEA_PP(2);
419
421 VARSIZE_ANY_EXHDR(delim));
422 if (isfirst)
423 state->cursor = VARSIZE_ANY_EXHDR(delim);
424 }
425
428 }
429
430 /*
431 * The transition type for string_agg() is declared to be "internal",
432 * which is a pass-by-value type the same size as a pointer.
433 */
434 if (state)
437}
438
439Datum
441{
443
444 /* cannot be called directly because of internal-type argument */
445 Assert(AggCheckCallContext(fcinfo, NULL));
446
448
449 if (state != NULL)
450 {
451 /* As per comment in transfn, strip data before the cursor position */
452 bytea *result;
453 int strippedlen = state->len - state->cursor;
454
455 result = (bytea *) palloc(strippedlen + VARHDRSZ);
456 SET_VARSIZE(result, strippedlen + VARHDRSZ);
457 memcpy(VARDATA(result), &state->data[state->cursor], strippedlen);
458 PG_RETURN_BYTEA_P(result);
459 }
460 else
462}
463
464/*-------------------------------------------------------------
465 * byteaoctetlen
466 *
467 * get the number of bytes contained in an instance of type 'bytea'
468 *-------------------------------------------------------------
469 */
470Datum
472{
474
475 /* We need not detoast the input at all */
477}
478
479/*
480 * byteacat -
481 * takes two bytea* and returns a bytea* that is the concatenation of
482 * the two.
483 *
484 * Cloned from textcat and modified as required.
485 */
486Datum
488{
489 bytea *t1 = PG_GETARG_BYTEA_PP(0);
490 bytea *t2 = PG_GETARG_BYTEA_PP(1);
491
493}
494
495/*
496 * byteaoverlay
497 * Replace specified substring of first string with second
498 *
499 * The SQL standard defines OVERLAY() in terms of substring and concatenation.
500 * This code is a direct implementation of what the standard says.
501 */
502Datum
504{
505 bytea *t1 = PG_GETARG_BYTEA_PP(0);
506 bytea *t2 = PG_GETARG_BYTEA_PP(1);
507 int sp = PG_GETARG_INT32(2); /* substring start position */
508 int sl = PG_GETARG_INT32(3); /* substring length */
509
510 PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
511}
512
513Datum
515{
516 bytea *t1 = PG_GETARG_BYTEA_PP(0);
517 bytea *t2 = PG_GETARG_BYTEA_PP(1);
518 int sp = PG_GETARG_INT32(2); /* substring start position */
519 int sl;
520
521 sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
522 PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
523}
524
525/*
526 * bytea_substr()
527 * Return a substring starting at the specified position.
528 * Cloned from text_substr and modified as required.
529 *
530 * Input:
531 * - string
532 * - starting position (is one-based)
533 * - string length (optional)
534 *
535 * If the starting position is zero or less, then return from the start of the string
536 * adjusting the length to be consistent with the "negative start" per SQL.
537 * If the length is less than zero, an ERROR is thrown. If no third argument
538 * (length) is provided, the length to the end of the string is assumed.
539 */
540Datum
542{
546 false));
547}
548
549/*
550 * bytea_substr_no_len -
551 * Wrapper to avoid opr_sanity failure due to
552 * one function accepting a different number of args.
553 */
554Datum
556{
559 -1,
560 true));
561}
562
563/*
564 * bit_count
565 */
566Datum
568{
569 bytea *t1 = PG_GETARG_BYTEA_PP(0);
570
572}
573
574/*
575 * byteapos -
576 * Return the position of the specified substring.
577 * Implements the SQL POSITION() function.
578 * Cloned from textpos and modified as required.
579 */
580Datum
582{
583 bytea *t1 = PG_GETARG_BYTEA_PP(0);
584 bytea *t2 = PG_GETARG_BYTEA_PP(1);
585 int pos;
586 int px,
587 p;
588 int len1,
589 len2;
590 char *p1,
591 *p2;
592
593 len1 = VARSIZE_ANY_EXHDR(t1);
594 len2 = VARSIZE_ANY_EXHDR(t2);
595
596 if (len2 <= 0)
597 PG_RETURN_INT32(1); /* result for empty pattern */
598
599 p1 = VARDATA_ANY(t1);
600 p2 = VARDATA_ANY(t2);
601
602 pos = 0;
603 px = (len1 - len2);
604 for (p = 0; p <= px; p++)
605 {
606 if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
607 {
608 pos = p + 1;
609 break;
610 };
611 p1++;
612 };
613
614 PG_RETURN_INT32(pos);
615}
616
617/*-------------------------------------------------------------
618 * byteaGetByte
619 *
620 * this routine treats "bytea" as an array of bytes.
621 * It returns the Nth byte (a number between 0 and 255).
622 *-------------------------------------------------------------
623 */
624Datum
626{
628 int32 n = PG_GETARG_INT32(1);
629 int len;
630 int byte;
631
633
634 if (n < 0 || n >= len)
636 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
637 errmsg("index %d out of valid range, 0..%d",
638 n, len - 1)));
639
640 byte = ((unsigned char *) VARDATA_ANY(v))[n];
641
642 PG_RETURN_INT32(byte);
643}
644
645/*-------------------------------------------------------------
646 * byteaGetBit
647 *
648 * This routine treats a "bytea" type like an array of bits.
649 * It returns the value of the Nth bit (0 or 1).
650 *
651 *-------------------------------------------------------------
652 */
653Datum
655{
657 int64 n = PG_GETARG_INT64(1);
658 int byteNo,
659 bitNo;
660 int len;
661 int byte;
662
664
665 if (n < 0 || n >= (int64) len * 8)
667 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
668 errmsg("index %" PRId64 " out of valid range, 0..%" PRId64,
669 n, (int64) len * 8 - 1)));
670
671 /* n/8 is now known < len, so safe to cast to int */
672 byteNo = (int) (n / 8);
673 bitNo = (int) (n % 8);
674
675 byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
676
677 if (byte & (1 << bitNo))
679 else
681}
682
683/*-------------------------------------------------------------
684 * byteaSetByte
685 *
686 * Given an instance of type 'bytea' creates a new one with
687 * the Nth byte set to the given value.
688 *
689 *-------------------------------------------------------------
690 */
691Datum
693{
695 int32 n = PG_GETARG_INT32(1);
696 int32 newByte = PG_GETARG_INT32(2);
697 int len;
698
699 len = VARSIZE(res) - VARHDRSZ;
700
701 if (n < 0 || n >= len)
703 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
704 errmsg("index %d out of valid range, 0..%d",
705 n, len - 1)));
706
707 /*
708 * Now set the byte.
709 */
710 ((unsigned char *) VARDATA(res))[n] = newByte;
711
713}
714
715/*-------------------------------------------------------------
716 * byteaSetBit
717 *
718 * Given an instance of type 'bytea' creates a new one with
719 * the Nth bit set to the given value.
720 *
721 *-------------------------------------------------------------
722 */
723Datum
725{
727 int64 n = PG_GETARG_INT64(1);
728 int32 newBit = PG_GETARG_INT32(2);
729 int len;
730 int oldByte,
731 newByte;
732 int byteNo,
733 bitNo;
734
735 len = VARSIZE(res) - VARHDRSZ;
736
737 if (n < 0 || n >= (int64) len * 8)
739 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
740 errmsg("index %" PRId64 " out of valid range, 0..%" PRId64,
741 n, (int64) len * 8 - 1)));
742
743 /* n/8 is now known < len, so safe to cast to int */
744 byteNo = (int) (n / 8);
745 bitNo = (int) (n % 8);
746
747 /*
748 * sanity check!
749 */
750 if (newBit != 0 && newBit != 1)
752 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
753 errmsg("new bit must be 0 or 1")));
754
755 /*
756 * Update the byte.
757 */
758 oldByte = ((unsigned char *) VARDATA(res))[byteNo];
759
760 if (newBit == 0)
761 newByte = oldByte & (~(1 << bitNo));
762 else
763 newByte = oldByte | (1 << bitNo);
764
765 ((unsigned char *) VARDATA(res))[byteNo] = newByte;
766
768}
769
770/*
771 * Return reversed bytea
772 */
773Datum
775{
777 const char *p = VARDATA_ANY(v);
778 int len = VARSIZE_ANY_EXHDR(v);
779 const char *endp = p + len;
780 bytea *result = palloc(len + VARHDRSZ);
781 char *dst = (char *) VARDATA(result) + len;
782
783 SET_VARSIZE(result, len + VARHDRSZ);
784
785 while (p < endp)
786 *(--dst) = *p++;
787
788 PG_RETURN_BYTEA_P(result);
789}
790
791
792/*****************************************************************************
793 * Comparison Functions used for bytea
794 *
795 * Note: btree indexes need these routines not to leak memory; therefore,
796 * be careful to free working copies of toasted datums. Most places don't
797 * need to be so careful.
798 *****************************************************************************/
799
800Datum
802{
803 Datum arg1 = PG_GETARG_DATUM(0);
804 Datum arg2 = PG_GETARG_DATUM(1);
805 bool result;
806 Size len1,
807 len2;
808
809 /*
810 * We can use a fast path for unequal lengths, which might save us from
811 * having to detoast one or both values.
812 */
813 len1 = toast_raw_datum_size(arg1);
814 len2 = toast_raw_datum_size(arg2);
815 if (len1 != len2)
816 result = false;
817 else
818 {
819 bytea *barg1 = DatumGetByteaPP(arg1);
820 bytea *barg2 = DatumGetByteaPP(arg2);
821
822 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
823 len1 - VARHDRSZ) == 0);
824
825 PG_FREE_IF_COPY(barg1, 0);
826 PG_FREE_IF_COPY(barg2, 1);
827 }
828
829 PG_RETURN_BOOL(result);
830}
831
832Datum
834{
835 Datum arg1 = PG_GETARG_DATUM(0);
836 Datum arg2 = PG_GETARG_DATUM(1);
837 bool result;
838 Size len1,
839 len2;
840
841 /*
842 * We can use a fast path for unequal lengths, which might save us from
843 * having to detoast one or both values.
844 */
845 len1 = toast_raw_datum_size(arg1);
846 len2 = toast_raw_datum_size(arg2);
847 if (len1 != len2)
848 result = true;
849 else
850 {
851 bytea *barg1 = DatumGetByteaPP(arg1);
852 bytea *barg2 = DatumGetByteaPP(arg2);
853
854 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
855 len1 - VARHDRSZ) != 0);
856
857 PG_FREE_IF_COPY(barg1, 0);
858 PG_FREE_IF_COPY(barg2, 1);
859 }
860
861 PG_RETURN_BOOL(result);
862}
863
864Datum
866{
867 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
868 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
869 int len1,
870 len2;
871 int cmp;
872
873 len1 = VARSIZE_ANY_EXHDR(arg1);
874 len2 = VARSIZE_ANY_EXHDR(arg2);
875
876 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
877
878 PG_FREE_IF_COPY(arg1, 0);
879 PG_FREE_IF_COPY(arg2, 1);
880
881 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
882}
883
884Datum
886{
887 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
888 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
889 int len1,
890 len2;
891 int cmp;
892
893 len1 = VARSIZE_ANY_EXHDR(arg1);
894 len2 = VARSIZE_ANY_EXHDR(arg2);
895
896 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
897
898 PG_FREE_IF_COPY(arg1, 0);
899 PG_FREE_IF_COPY(arg2, 1);
900
901 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
902}
903
904Datum
906{
907 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
908 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
909 int len1,
910 len2;
911 int cmp;
912
913 len1 = VARSIZE_ANY_EXHDR(arg1);
914 len2 = VARSIZE_ANY_EXHDR(arg2);
915
916 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
917
918 PG_FREE_IF_COPY(arg1, 0);
919 PG_FREE_IF_COPY(arg2, 1);
920
921 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
922}
923
924Datum
926{
927 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
928 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
929 int len1,
930 len2;
931 int cmp;
932
933 len1 = VARSIZE_ANY_EXHDR(arg1);
934 len2 = VARSIZE_ANY_EXHDR(arg2);
935
936 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
937
938 PG_FREE_IF_COPY(arg1, 0);
939 PG_FREE_IF_COPY(arg2, 1);
940
941 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
942}
943
944Datum
946{
947 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
948 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
949 int len1,
950 len2;
951 int cmp;
952
953 len1 = VARSIZE_ANY_EXHDR(arg1);
954 len2 = VARSIZE_ANY_EXHDR(arg2);
955
956 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
957 if ((cmp == 0) && (len1 != len2))
958 cmp = (len1 < len2) ? -1 : 1;
959
960 PG_FREE_IF_COPY(arg1, 0);
961 PG_FREE_IF_COPY(arg2, 1);
962
964}
965
966Datum
968{
969 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
970 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
971 bytea *result;
972 int len1,
973 len2;
974 int cmp;
975
976 len1 = VARSIZE_ANY_EXHDR(arg1);
977 len2 = VARSIZE_ANY_EXHDR(arg2);
978
979 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
980 result = ((cmp > 0) || ((cmp == 0) && (len1 > len2)) ? arg1 : arg2);
981
982 PG_RETURN_BYTEA_P(result);
983}
984
985Datum
987{
988 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
989 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
990 bytea *result;
991 int len1,
992 len2;
993 int cmp;
994
995 len1 = VARSIZE_ANY_EXHDR(arg1);
996 len2 = VARSIZE_ANY_EXHDR(arg2);
997
998 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
999 result = ((cmp < 0) || ((cmp == 0) && (len1 < len2)) ? arg1 : arg2);
1000
1001 PG_RETURN_BYTEA_P(result);
1002}
1003
1004Datum
1006{
1008 MemoryContext oldcontext;
1009
1010 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1011
1012 /* Use generic string SortSupport, forcing "C" collation */
1013 varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
1014
1015 MemoryContextSwitchTo(oldcontext);
1016
1018}
1019
1020/* Cast bytea -> int2 */
1021Datum
1023{
1024 bytea *v = PG_GETARG_BYTEA_PP(0);
1025 int len = VARSIZE_ANY_EXHDR(v);
1026 uint16 result;
1027
1028 /* Check that the byte array is not too long */
1029 if (len > sizeof(result))
1030 ereport(ERROR,
1031 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1032 errmsg("smallint out of range"));
1033
1034 /* Convert it to an integer; most significant bytes come first */
1035 result = 0;
1036 for (int i = 0; i < len; i++)
1037 {
1038 result <<= BITS_PER_BYTE;
1039 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1040 }
1041
1042 PG_RETURN_INT16(result);
1043}
1044
1045/* Cast bytea -> int4 */
1046Datum
1048{
1049 bytea *v = PG_GETARG_BYTEA_PP(0);
1050 int len = VARSIZE_ANY_EXHDR(v);
1051 uint32 result;
1052
1053 /* Check that the byte array is not too long */
1054 if (len > sizeof(result))
1055 ereport(ERROR,
1056 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1057 errmsg("integer out of range"));
1058
1059 /* Convert it to an integer; most significant bytes come first */
1060 result = 0;
1061 for (int i = 0; i < len; i++)
1062 {
1063 result <<= BITS_PER_BYTE;
1064 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1065 }
1066
1067 PG_RETURN_INT32(result);
1068}
1069
1070/* Cast bytea -> int8 */
1071Datum
1073{
1074 bytea *v = PG_GETARG_BYTEA_PP(0);
1075 int len = VARSIZE_ANY_EXHDR(v);
1076 uint64 result;
1077
1078 /* Check that the byte array is not too long */
1079 if (len > sizeof(result))
1080 ereport(ERROR,
1081 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1082 errmsg("bigint out of range"));
1083
1084 /* Convert it to an integer; most significant bytes come first */
1085 result = 0;
1086 for (int i = 0; i < len; i++)
1087 {
1088 result <<= BITS_PER_BYTE;
1089 result |= ((unsigned char *) VARDATA_ANY(v))[i];
1090 }
1091
1092 PG_RETURN_INT64(result);
1093}
1094
1095/* Cast int2 -> bytea; can just use int2send() */
1096Datum
1098{
1099 return int2send(fcinfo);
1100}
1101
1102/* Cast int4 -> bytea; can just use int4send() */
1103Datum
1105{
1106 return int4send(fcinfo);
1107}
1108
1109/* Cast int8 -> bytea; can just use int8send() */
1110Datum
1112{
1113 return int8send(fcinfo);
1114}
Datum byteacat(PG_FUNCTION_ARGS)
Definition: bytea.c:487
Datum byteaoverlay(PG_FUNCTION_ARGS)
Definition: bytea.c:503
int bytea_output
Definition: bytea.c:33
Datum byteaeq(PG_FUNCTION_ARGS)
Definition: bytea.c:801
#define DIG(VAL)
Definition: bytea.c:178
Datum byteagt(PG_FUNCTION_ARGS)
Definition: bytea.c:905
Datum bytea_int2(PG_FUNCTION_ARGS)
Definition: bytea.c:1022
Datum bytea_string_agg_finalfn(PG_FUNCTION_ARGS)
Definition: bytea.c:440
Datum int2_bytea(PG_FUNCTION_ARGS)
Definition: bytea.c:1097
Datum byteapos(PG_FUNCTION_ARGS)
Definition: bytea.c:581
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: bytea.c:144
Datum byteane(PG_FUNCTION_ARGS)
Definition: bytea.c:833
Datum byteage(PG_FUNCTION_ARGS)
Definition: bytea.c:925
Datum byteacmp(PG_FUNCTION_ARGS)
Definition: bytea.c:945
Datum byteaGetBit(PG_FUNCTION_ARGS)
Definition: bytea.c:654
Datum bytea_bit_count(PG_FUNCTION_ARGS)
Definition: bytea.c:567
Datum byteaSetBit(PG_FUNCTION_ARGS)
Definition: bytea.c:724
Datum byteaSetByte(PG_FUNCTION_ARGS)
Definition: bytea.c:692
Datum bytea_substr_no_len(PG_FUNCTION_ARGS)
Definition: bytea.c:555
Datum byteale(PG_FUNCTION_ARGS)
Definition: bytea.c:885
#define PG_STR_GET_BYTEA(str_)
Definition: bytea.c:80
Datum int8_bytea(PG_FUNCTION_ARGS)
Definition: bytea.c:1111
Datum bytea_int4(PG_FUNCTION_ARGS)
Definition: bytea.c:1047
Datum bytearecv(PG_FUNCTION_ARGS)
Definition: bytea.c:344
Datum bytea_smaller(PG_FUNCTION_ARGS)
Definition: bytea.c:986
Datum bytea_sortsupport(PG_FUNCTION_ARGS)
Definition: bytea.c:1005
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: bytea.c:84
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: bytea.c:47
Datum bytea_reverse(PG_FUNCTION_ARGS)
Definition: bytea.c:774
Datum byteaoverlay_no_len(PG_FUNCTION_ARGS)
Definition: bytea.c:514
Datum bytea_int8(PG_FUNCTION_ARGS)
Definition: bytea.c:1072
Datum bytea_larger(PG_FUNCTION_ARGS)
Definition: bytea.c:967
Datum byteaoctetlen(PG_FUNCTION_ARGS)
Definition: bytea.c:471
Datum byteaout(PG_FUNCTION_ARGS)
Definition: bytea.c:261
Datum byteain(PG_FUNCTION_ARGS)
Definition: bytea.c:187
Datum bytea_string_agg_transfn(PG_FUNCTION_ARGS)
Definition: bytea.c:371
Datum byteaGetByte(PG_FUNCTION_ARGS)
Definition: bytea.c:625
Datum int4_bytea(PG_FUNCTION_ARGS)
Definition: bytea.c:1104
#define VAL(CH)
Definition: bytea.c:177
Datum bytea_substr(PG_FUNCTION_ARGS)
Definition: bytea.c:541
Datum bytealt(PG_FUNCTION_ARGS)
Definition: bytea.c:865
Datum byteasend(PG_FUNCTION_ARGS)
Definition: bytea.c:363
@ BYTEA_OUTPUT_HEX
Definition: bytea.h:22
@ BYTEA_OUTPUT_ESCAPE
Definition: bytea.h:21
#define Min(x, y)
Definition: c.h:1003
#define Max(x, y)
Definition: c.h:997
#define VARHDRSZ
Definition: c.h:697
int64_t int64
Definition: c.h:535
int32_t int32
Definition: c.h:534
uint64_t uint64
Definition: c.h:539
uint16_t uint16
Definition: c.h:537
uint32_t uint32
Definition: c.h:538
size_t Size
Definition: c.h:610
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1161
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#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:217
uint64 hex_encode(const char *src, size_t len, char *dst)
Definition: encode.c:181
#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)
Assert(PointerIsAligned(start, uint64))
const char * str
long val
Definition: informix.c:689
static struct @168 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 i
Definition: isn.c:77
void * palloc(Size size)
Definition: mcxt.c:1365
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4613
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.h:363
#define BITS_PER_BYTE
const void size_t len
static char * buf
Definition: pg_test_fsync.c:72
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:528
char * s1
char * s2
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743
#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
MemoryContext ssup_cxt
Definition: sortsupport.h:66
Definition: regguts.h:323
Definition: c.h:692
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
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1615