1 /*-------------------------------------------------------------------------
4 * Functions for the variable-length built-in types.
6 * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.76 2001/11/19 09:05:02 tgl Exp $
13 *-------------------------------------------------------------------------
19 #include "mb/pg_wchar.h"
20 #include "miscadmin.h"
21 #include "utils/builtins.h"
23 static int text_cmp(text *arg1, text *arg2);
26 /*****************************************************************************
28 *****************************************************************************/
31 #define VAL(CH) ((CH) - '0')
32 #define DIG(VAL) ((VAL) + '0')
35 * byteain - converts from printable representation of byte array
37 * Non-printable characters must be passed as '\nnn' (octal) and are
38 * converted to internal form. '\' must be passed as '\\'.
39 * elog(ERROR, ...) if bad form.
42 * The input is scaned twice.
43 * The error checking of input is minimal.
46 byteain(PG_FUNCTION_ARGS)
48 char *inputText = PG_GETARG_CSTRING(0);
54 for (byte = 0, tp = inputText; *tp != '\0'; byte++)
58 else if ((tp[0] == '\\') &&
59 (tp[1] >= '0' && tp[1] <= '3') &&
60 (tp[2] >= '0' && tp[2] <= '7') &&
61 (tp[3] >= '0' && tp[3] <= '7'))
63 else if ((tp[0] == '\\') &&
69 * one backslash, not followed by 0 or ### valid octal
71 elog(ERROR, "Bad input string for type bytea");
76 result = (bytea *) palloc(byte);
77 result->vl_len = byte; /* set varlena length */
85 else if ((tp[0] == '\\') &&
86 (tp[1] >= '0' && tp[1] <= '3') &&
87 (tp[2] >= '0' && tp[2] <= '7') &&
88 (tp[3] >= '0' && tp[3] <= '7'))
94 *rp++ = byte + VAL(tp[3]);
97 else if ((tp[0] == '\\') &&
106 * We should never get here. The first pass should not allow
109 elog(ERROR, "Bad input string for type bytea");
113 PG_RETURN_BYTEA_P(result);
117 * byteaout - converts to printable representation of byte array
119 * Non-printable characters are inserted as '\nnn' (octal) and '\' as
122 * NULL vlena should be an error--returning string with NULL for now.
125 byteaout(PG_FUNCTION_ARGS)
127 bytea *vlena = PG_GETARG_BYTEA_P(0);
131 int val; /* holds unprintable chars */
135 len = 1; /* empty string has 1 char */
137 for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
141 else if (isprint((unsigned char) *vp))
146 rp = result = (char *) palloc(len);
148 for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
155 else if (isprint((unsigned char) *vp))
161 rp[3] = DIG(val & 07);
163 rp[2] = DIG(val & 07);
165 rp[1] = DIG(val & 03);
170 PG_RETURN_CSTRING(result);
175 * textin - converts "..." to internal representation
178 textin(PG_FUNCTION_ARGS)
180 char *inputText = PG_GETARG_CSTRING(0);
188 len = strlen(inputText) + VARHDRSZ;
191 if ((ermsg = pg_verifymbstr(inputText, len - VARHDRSZ)))
192 elog(ERROR, "%s", ermsg);
195 result = (text *) palloc(len);
196 VARATT_SIZEP(result) = len;
198 memcpy(VARDATA(result), inputText, len - VARHDRSZ);
201 convertstr(VARDATA(result), len - VARHDRSZ, 0);
204 PG_RETURN_TEXT_P(result);
208 * textout - converts internal representation to "..."
211 textout(PG_FUNCTION_ARGS)
213 text *t = PG_GETARG_TEXT_P(0);
217 len = VARSIZE(t) - VARHDRSZ;
218 result = (char *) palloc(len + 1);
219 memcpy(result, VARDATA(t), len);
223 convertstr(result, len, 1);
226 PG_RETURN_CSTRING(result);
230 /* ========== PUBLIC ROUTINES ========== */
234 * returns the logical length of a text*
235 * (which is less than the VARSIZE of the text*)
238 textlen(PG_FUNCTION_ARGS)
240 text *t = PG_GETARG_TEXT_P(0);
243 /* optimization for single byte encoding */
244 if (pg_database_encoding_max_length() <= 1)
245 PG_RETURN_INT32(VARSIZE(t) - VARHDRSZ);
248 pg_mbstrlen_with_len(VARDATA(t), VARSIZE(t) - VARHDRSZ)
251 PG_RETURN_INT32(VARSIZE(t) - VARHDRSZ);
257 * returns the physical length of a text*
258 * (which is less than the VARSIZE of the text*)
260 * XXX is it actually appropriate to return the compressed length
261 * when the value is compressed? It's not at all clear to me that
262 * this is what SQL92 has in mind ...
265 textoctetlen(PG_FUNCTION_ARGS)
267 struct varattrib *t = (struct varattrib *) PG_GETARG_RAW_VARLENA_P(0);
269 if (!VARATT_IS_EXTERNAL(t))
270 PG_RETURN_INT32(VARATT_SIZE(t) - VARHDRSZ);
272 PG_RETURN_INT32(t->va_content.va_external.va_extsize);
277 * takes two text* and returns a text* that is the concatenation of
280 * Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
281 * Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10.
282 * Allocate space for output in all cases.
283 * XXX - thomas 1997-07-10
286 textcat(PG_FUNCTION_ARGS)
288 text *t1 = PG_GETARG_TEXT_P(0);
289 text *t2 = PG_GETARG_TEXT_P(1);
296 len1 = (VARSIZE(t1) - VARHDRSZ);
300 len2 = (VARSIZE(t2) - VARHDRSZ);
304 len = len1 + len2 + VARHDRSZ;
305 result = (text *) palloc(len);
307 /* Set size of result string... */
308 VARATT_SIZEP(result) = len;
310 /* Fill data field of result string... */
311 ptr = VARDATA(result);
313 memcpy(ptr, VARDATA(t1), len1);
315 memcpy(ptr + len1, VARDATA(t2), len2);
317 PG_RETURN_TEXT_P(result);
322 * Return a substring starting at the specified position.
323 * - thomas 1997-12-31
327 * - starting position (is one-based)
330 * If the starting position is zero or less, then return from the start of the string
331 * adjusting the length to be consistent with the "negative start" per SQL92.
332 * If the length is less than zero, return the remaining string.
334 * Note that the arguments operate on octet length,
335 * so not aware of multi-byte character sets.
337 * Added multi-byte support.
338 * - Tatsuo Ishii 1998-4-21
339 * Changed behavior if starting position is less than one to conform to SQL92 behavior.
340 * Formerly returned the entire string; now returns a portion.
341 * - Thomas Lockhart 1998-12-10
344 text_substr(PG_FUNCTION_ARGS)
346 text *string = PG_GETARG_TEXT_P(0);
347 int32 m = PG_GETARG_INT32(1);
348 int32 n = PG_GETARG_INT32(2);
357 len = VARSIZE(string) - VARHDRSZ;
359 len = pg_mbstrlen_with_len(VARDATA(string), len);
362 /* starting position after the end of the string? */
370 * starting position before the start of the string? then offset into
371 * the string per SQL92 spec...
379 /* m will now become a zero-based starting position */
381 if (((m + n) > len) || (n < 0))
386 for (i = 0; i < m; i++)
388 m = p - VARDATA(string);
389 for (i = 0; i < n; i++)
391 n = p - (VARDATA(string) + m);
394 ret = (text *) palloc(VARHDRSZ + n);
395 VARATT_SIZEP(ret) = VARHDRSZ + n;
397 memcpy(VARDATA(ret), VARDATA(string) + m, n);
399 PG_RETURN_TEXT_P(ret);
404 * Return the position of the specified substring.
405 * Implements the SQL92 POSITION() function.
406 * Ref: A Guide To The SQL Standard, Date & Darwen, 1997
407 * - thomas 1997-07-27
409 * Added multi-byte support.
410 * - Tatsuo Ishii 1998-4-21
413 textpos(PG_FUNCTION_ARGS)
415 text *t1 = PG_GETARG_TEXT_P(0);
416 text *t2 = PG_GETARG_TEXT_P(1);
430 if (VARSIZE(t2) <= VARHDRSZ)
431 PG_RETURN_INT32(1); /* result for empty pattern */
433 len1 = (VARSIZE(t1) - VARHDRSZ);
434 len2 = (VARSIZE(t2) - VARHDRSZ);
436 ps1 = p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar));
437 (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(t1), p1, len1);
438 len1 = pg_wchar_strlen(p1);
439 ps2 = p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar));
440 (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(t2), p2, len2);
441 len2 = pg_wchar_strlen(p2);
448 for (p = 0; p <= px; p++)
451 if ((*p2 == *p1) && (pg_wchar_strncmp(p1, p2, len2) == 0))
453 if ((*p2 == *p1) && (strncmp(p1, p2, len2) == 0))
465 PG_RETURN_INT32(pos);
469 * Comparison function for text strings with given lengths.
470 * Includes locale support, but must copy strings to temporary memory
471 * to allow null-termination for inputs to strcoll().
475 varstr_cmp(char *arg1, int len1, char *arg2, int len2)
482 a1p = (char *) palloc(len1 + 1);
483 a2p = (char *) palloc(len2 + 1);
485 memcpy(a1p, arg1, len1);
486 *(a1p + len1) = '\0';
487 memcpy(a2p, arg2, len2);
488 *(a2p + len2) = '\0';
490 result = strcoll(a1p, a2p);
500 result = strncmp(a1p, a2p, Min(len1, len2));
501 if ((result == 0) && (len1 != len2))
502 result = (len1 < len2) ? -1 : 1;
510 * Internal comparison function for text strings.
514 text_cmp(text *arg1, text *arg2)
524 len1 = VARSIZE(arg1) - VARHDRSZ;
525 len2 = VARSIZE(arg2) - VARHDRSZ;
527 return varstr_cmp(a1p, len1, a2p, len2);
531 * Comparison functions for text strings.
533 * Note: btree indexes need these routines not to leak memory; therefore,
534 * be careful to free working copies of toasted datums. Most places don't
535 * need to be so careful.
539 texteq(PG_FUNCTION_ARGS)
541 text *arg1 = PG_GETARG_TEXT_P(0);
542 text *arg2 = PG_GETARG_TEXT_P(1);
545 /* fast path for different-length inputs */
546 if (VARSIZE(arg1) != VARSIZE(arg2))
549 result = (text_cmp(arg1, arg2) == 0);
551 PG_FREE_IF_COPY(arg1, 0);
552 PG_FREE_IF_COPY(arg2, 1);
554 PG_RETURN_BOOL(result);
558 textne(PG_FUNCTION_ARGS)
560 text *arg1 = PG_GETARG_TEXT_P(0);
561 text *arg2 = PG_GETARG_TEXT_P(1);
564 /* fast path for different-length inputs */
565 if (VARSIZE(arg1) != VARSIZE(arg2))
568 result = (text_cmp(arg1, arg2) != 0);
570 PG_FREE_IF_COPY(arg1, 0);
571 PG_FREE_IF_COPY(arg2, 1);
573 PG_RETURN_BOOL(result);
577 text_lt(PG_FUNCTION_ARGS)
579 text *arg1 = PG_GETARG_TEXT_P(0);
580 text *arg2 = PG_GETARG_TEXT_P(1);
583 result = (text_cmp(arg1, arg2) < 0);
585 PG_FREE_IF_COPY(arg1, 0);
586 PG_FREE_IF_COPY(arg2, 1);
588 PG_RETURN_BOOL(result);
592 text_le(PG_FUNCTION_ARGS)
594 text *arg1 = PG_GETARG_TEXT_P(0);
595 text *arg2 = PG_GETARG_TEXT_P(1);
598 result = (text_cmp(arg1, arg2) <= 0);
600 PG_FREE_IF_COPY(arg1, 0);
601 PG_FREE_IF_COPY(arg2, 1);
603 PG_RETURN_BOOL(result);
607 text_gt(PG_FUNCTION_ARGS)
609 text *arg1 = PG_GETARG_TEXT_P(0);
610 text *arg2 = PG_GETARG_TEXT_P(1);
613 result = (text_cmp(arg1, arg2) > 0);
615 PG_FREE_IF_COPY(arg1, 0);
616 PG_FREE_IF_COPY(arg2, 1);
618 PG_RETURN_BOOL(result);
622 text_ge(PG_FUNCTION_ARGS)
624 text *arg1 = PG_GETARG_TEXT_P(0);
625 text *arg2 = PG_GETARG_TEXT_P(1);
628 result = (text_cmp(arg1, arg2) >= 0);
630 PG_FREE_IF_COPY(arg1, 0);
631 PG_FREE_IF_COPY(arg2, 1);
633 PG_RETURN_BOOL(result);
637 bttextcmp(PG_FUNCTION_ARGS)
639 text *arg1 = PG_GETARG_TEXT_P(0);
640 text *arg2 = PG_GETARG_TEXT_P(1);
643 result = text_cmp(arg1, arg2);
645 PG_FREE_IF_COPY(arg1, 0);
646 PG_FREE_IF_COPY(arg2, 1);
648 PG_RETURN_INT32(result);
653 text_larger(PG_FUNCTION_ARGS)
655 text *arg1 = PG_GETARG_TEXT_P(0);
656 text *arg2 = PG_GETARG_TEXT_P(1);
659 result = ((text_cmp(arg1, arg2) > 0) ? arg1 : arg2);
661 PG_RETURN_TEXT_P(result);
665 text_smaller(PG_FUNCTION_ARGS)
667 text *arg1 = PG_GETARG_TEXT_P(0);
668 text *arg2 = PG_GETARG_TEXT_P(1);
671 result = ((text_cmp(arg1, arg2) < 0) ? arg1 : arg2);
673 PG_RETURN_TEXT_P(result);
676 /*-------------------------------------------------------------
679 * get the number of bytes contained in an instance of type 'bytea'
680 *-------------------------------------------------------------
683 byteaoctetlen(PG_FUNCTION_ARGS)
685 bytea *v = PG_GETARG_BYTEA_P(0);
687 PG_RETURN_INT32(VARSIZE(v) - VARHDRSZ);
692 * takes two bytea* and returns a bytea* that is the concatenation of
695 * Cloned from textcat and modified as required.
698 byteacat(PG_FUNCTION_ARGS)
700 bytea *t1 = PG_GETARG_BYTEA_P(0);
701 bytea *t2 = PG_GETARG_BYTEA_P(1);
708 len1 = (VARSIZE(t1) - VARHDRSZ);
712 len2 = (VARSIZE(t2) - VARHDRSZ);
716 len = len1 + len2 + VARHDRSZ;
717 result = (bytea *) palloc(len);
719 /* Set size of result string... */
720 VARATT_SIZEP(result) = len;
722 /* Fill data field of result string... */
723 ptr = VARDATA(result);
725 memcpy(ptr, VARDATA(t1), len1);
727 memcpy(ptr + len1, VARDATA(t2), len2);
729 PG_RETURN_BYTEA_P(result);
734 * Return a substring starting at the specified position.
735 * Cloned from text_substr and modified as required.
739 * - starting position (is one-based)
742 * If the starting position is zero or less, then return from the start of the string
743 * adjusting the length to be consistent with the "negative start" per SQL92.
744 * If the length is less than zero, return the remaining string.
748 bytea_substr(PG_FUNCTION_ARGS)
750 bytea *string = PG_GETARG_BYTEA_P(0);
751 int32 m = PG_GETARG_INT32(1);
752 int32 n = PG_GETARG_INT32(2);
756 len = VARSIZE(string) - VARHDRSZ;
758 /* starting position after the end of the string? */
766 * starting position before the start of the string? then offset into
767 * the string per SQL92 spec...
775 /* m will now become a zero-based starting position */
777 if (((m + n) > len) || (n < 0))
780 ret = (bytea *) palloc(VARHDRSZ + n);
781 VARATT_SIZEP(ret) = VARHDRSZ + n;
783 memcpy(VARDATA(ret), VARDATA(string) + m, n);
785 PG_RETURN_BYTEA_P(ret);
790 * Return the position of the specified substring.
791 * Implements the SQL92 POSITION() function.
792 * Cloned from textpos and modified as required.
795 byteapos(PG_FUNCTION_ARGS)
797 bytea *t1 = PG_GETARG_BYTEA_P(0);
798 bytea *t2 = PG_GETARG_BYTEA_P(1);
807 if (VARSIZE(t2) <= VARHDRSZ)
808 PG_RETURN_INT32(1); /* result for empty pattern */
810 len1 = (VARSIZE(t1) - VARHDRSZ);
811 len2 = (VARSIZE(t2) - VARHDRSZ);
818 for (p = 0; p <= px; p++)
820 if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
828 PG_RETURN_INT32(pos);
831 /*-------------------------------------------------------------
834 * this routine treats "bytea" as an array of bytes.
835 * It returns the Nth byte (a number between 0 and 255).
836 *-------------------------------------------------------------
839 byteaGetByte(PG_FUNCTION_ARGS)
841 bytea *v = PG_GETARG_BYTEA_P(0);
842 int32 n = PG_GETARG_INT32(1);
846 len = VARSIZE(v) - VARHDRSZ;
848 if (n < 0 || n >= len)
849 elog(ERROR, "byteaGetByte: index %d out of range [0..%d]",
852 byte = ((unsigned char *) VARDATA(v))[n];
854 PG_RETURN_INT32(byte);
857 /*-------------------------------------------------------------
860 * This routine treats a "bytea" type like an array of bits.
861 * It returns the value of the Nth bit (0 or 1).
863 *-------------------------------------------------------------
866 byteaGetBit(PG_FUNCTION_ARGS)
868 bytea *v = PG_GETARG_BYTEA_P(0);
869 int32 n = PG_GETARG_INT32(1);
875 len = VARSIZE(v) - VARHDRSZ;
877 if (n < 0 || n >= len * 8)
878 elog(ERROR, "byteaGetBit: index %d out of range [0..%d]",
884 byte = ((unsigned char *) VARDATA(v))[byteNo];
886 if (byte & (1 << bitNo))
892 /*-------------------------------------------------------------
895 * Given an instance of type 'bytea' creates a new one with
896 * the Nth byte set to the given value.
898 *-------------------------------------------------------------
901 byteaSetByte(PG_FUNCTION_ARGS)
903 bytea *v = PG_GETARG_BYTEA_P(0);
904 int32 n = PG_GETARG_INT32(1);
905 int32 newByte = PG_GETARG_INT32(2);
909 len = VARSIZE(v) - VARHDRSZ;
911 if (n < 0 || n >= len)
912 elog(ERROR, "byteaSetByte: index %d out of range [0..%d]",
916 * Make a copy of the original varlena.
918 res = (bytea *) palloc(VARSIZE(v));
919 memcpy((char *) res, (char *) v, VARSIZE(v));
924 ((unsigned char *) VARDATA(res))[n] = newByte;
926 PG_RETURN_BYTEA_P(res);
929 /*-------------------------------------------------------------
932 * Given an instance of type 'bytea' creates a new one with
933 * the Nth bit set to the given value.
935 *-------------------------------------------------------------
938 byteaSetBit(PG_FUNCTION_ARGS)
940 bytea *v = PG_GETARG_BYTEA_P(0);
941 int32 n = PG_GETARG_INT32(1);
942 int32 newBit = PG_GETARG_INT32(2);
950 len = VARSIZE(v) - VARHDRSZ;
952 if (n < 0 || n >= len * 8)
953 elog(ERROR, "byteaSetBit: index %d out of range [0..%d]",
962 if (newBit != 0 && newBit != 1)
963 elog(ERROR, "byteaSetBit: new bit must be 0 or 1");
966 * Make a copy of the original varlena.
968 res = (bytea *) palloc(VARSIZE(v));
969 memcpy((char *) res, (char *) v, VARSIZE(v));
974 oldByte = ((unsigned char *) VARDATA(res))[byteNo];
977 newByte = oldByte & (~(1 << bitNo));
979 newByte = oldByte | (1 << bitNo);
981 ((unsigned char *) VARDATA(res))[byteNo] = newByte;
983 PG_RETURN_BYTEA_P(res);
988 * Converts a text type to a Name type.
991 text_name(PG_FUNCTION_ARGS)
993 text *s = PG_GETARG_TEXT_P(0);
997 len = VARSIZE(s) - VARHDRSZ;
999 /* Truncate oversize input */
1000 if (len >= NAMEDATALEN)
1001 len = NAMEDATALEN - 1;
1004 printf("text- convert string length %d (%d) ->%d\n",
1005 VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
1008 result = (Name) palloc(NAMEDATALEN);
1009 memcpy(NameStr(*result), VARDATA(s), len);
1011 /* now null pad to full length... */
1012 while (len < NAMEDATALEN)
1014 *(NameStr(*result) + len) = '\0';
1018 PG_RETURN_NAME(result);
1022 * Converts a Name type to a text type.
1025 name_text(PG_FUNCTION_ARGS)
1027 Name s = PG_GETARG_NAME(0);
1031 len = strlen(NameStr(*s));
1034 printf("text- convert string length %d (%d) ->%d\n",
1035 VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
1038 result = palloc(VARHDRSZ + len);
1039 VARATT_SIZEP(result) = VARHDRSZ + len;
1040 memcpy(VARDATA(result), NameStr(*s), len);
1042 PG_RETURN_TEXT_P(result);
1046 /*****************************************************************************
1047 * Comparison Functions used for bytea
1049 * Note: btree indexes need these routines not to leak memory; therefore,
1050 * be careful to free working copies of toasted datums. Most places don't
1051 * need to be so careful.
1052 *****************************************************************************/
1055 byteaeq(PG_FUNCTION_ARGS)
1057 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1058 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1063 len1 = VARSIZE(arg1) - VARHDRSZ;
1064 len2 = VARSIZE(arg2) - VARHDRSZ;
1066 /* fast path for different-length inputs */
1070 result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
1072 PG_FREE_IF_COPY(arg1, 0);
1073 PG_FREE_IF_COPY(arg2, 1);
1075 PG_RETURN_BOOL(result);
1079 byteane(PG_FUNCTION_ARGS)
1081 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1082 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1087 len1 = VARSIZE(arg1) - VARHDRSZ;
1088 len2 = VARSIZE(arg2) - VARHDRSZ;
1090 /* fast path for different-length inputs */
1094 result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
1096 PG_FREE_IF_COPY(arg1, 0);
1097 PG_FREE_IF_COPY(arg2, 1);
1099 PG_RETURN_BOOL(result);
1103 bytealt(PG_FUNCTION_ARGS)
1105 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1106 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1111 len1 = VARSIZE(arg1) - VARHDRSZ;
1112 len2 = VARSIZE(arg2) - VARHDRSZ;
1114 cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1116 PG_FREE_IF_COPY(arg1, 0);
1117 PG_FREE_IF_COPY(arg2, 1);
1119 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
1123 byteale(PG_FUNCTION_ARGS)
1125 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1126 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1131 len1 = VARSIZE(arg1) - VARHDRSZ;
1132 len2 = VARSIZE(arg2) - VARHDRSZ;
1134 cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1136 PG_FREE_IF_COPY(arg1, 0);
1137 PG_FREE_IF_COPY(arg2, 1);
1139 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
1143 byteagt(PG_FUNCTION_ARGS)
1145 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1146 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1151 len1 = VARSIZE(arg1) - VARHDRSZ;
1152 len2 = VARSIZE(arg2) - VARHDRSZ;
1154 cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1156 PG_FREE_IF_COPY(arg1, 0);
1157 PG_FREE_IF_COPY(arg2, 1);
1159 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
1163 byteage(PG_FUNCTION_ARGS)
1165 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1166 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1171 len1 = VARSIZE(arg1) - VARHDRSZ;
1172 len2 = VARSIZE(arg2) - VARHDRSZ;
1174 cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1176 PG_FREE_IF_COPY(arg1, 0);
1177 PG_FREE_IF_COPY(arg2, 1);
1179 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
1183 byteacmp(PG_FUNCTION_ARGS)
1185 bytea *arg1 = PG_GETARG_BYTEA_P(0);
1186 bytea *arg2 = PG_GETARG_BYTEA_P(1);
1191 len1 = VARSIZE(arg1) - VARHDRSZ;
1192 len2 = VARSIZE(arg2) - VARHDRSZ;
1194 cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
1195 if ((cmp == 0) && (len1 != len2))
1196 cmp = (len1 < len2) ? -1 : 1;
1198 PG_FREE_IF_COPY(arg1, 0);
1199 PG_FREE_IF_COPY(arg2, 1);
1201 PG_RETURN_INT32(cmp);