1 /*-------------------------------------------------------------------------
4 * Functions for the built-in types char(n) and varchar(n).
6 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.133 2010/01/02 16:57:55 momjian Exp $
13 *-------------------------------------------------------------------------
18 #include "access/hash.h"
19 #include "access/tuptoaster.h"
20 #include "libpq/pqformat.h"
21 #include "utils/array.h"
22 #include "utils/builtins.h"
23 #include "mb/pg_wchar.h"
26 /* common code for bpchartypmodin and varchartypmodin */
28 anychar_typmodin(ArrayType *ta, const char *typename)
34 tl = ArrayGetIntegerTypmods(ta, &n);
37 * we're not too tense about good error message here because grammar
38 * shouldn't allow wrong number of modifiers for CHAR
42 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
43 errmsg("invalid type modifier")));
47 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
48 errmsg("length for type %s must be at least 1", typename)));
49 if (*tl > MaxAttrSize)
51 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
52 errmsg("length for type %s cannot exceed %d",
53 typename, MaxAttrSize)));
56 * For largely historical reasons, the typmod is VARHDRSZ plus the number
57 * of characters; there is enough client-side code that knows about that
58 * that we'd better not change it.
60 typmod = VARHDRSZ + *tl;
65 /* common code for bpchartypmodout and varchartypmodout */
67 anychar_typmodout(int32 typmod)
69 char *res = (char *) palloc(64);
71 if (typmod > VARHDRSZ)
72 snprintf(res, 64, "(%d)", (int) (typmod - VARHDRSZ));
81 * CHAR() and VARCHAR() types are part of the SQL standard. CHAR()
82 * is for blank-padded string whose length is specified in CREATE TABLE.
83 * VARCHAR is for storing string whose length is at most the length specified
84 * at CREATE TABLE time.
86 * It's hard to implement these types because we cannot figure out
87 * the length of the type from the type itself. I changed (hopefully all) the
88 * fmgr calls that invoke input functions of a data type to supply the
89 * length also. (eg. in INSERTs, we have the tupleDescriptor which contains
90 * the length of the attributes and hence the exact length of the char() or
91 * varchar(). We pass this to bpcharin() or varcharin().) In the case where
92 * we cannot determine the length, we pass in -1 instead and the input
93 * converter does not enforce any length check.
95 * We actually implement this as a varlena so that we don't have to pass in
96 * the length for the comparison functions. (The difference between these
97 * types and "text" is that we truncate and possibly blank-pad the string
104 /*****************************************************************************
106 *****************************************************************************/
109 * bpchar_input -- common guts of bpcharin and bpcharrecv
111 * s is the input text of length len (may not be null-terminated)
112 * atttypmod is the typmod value to apply
114 * Note that atttypmod is measured in characters, which
115 * is not necessarily the same as the number of bytes.
117 * If the input string is too long, raise an error, unless the extra
118 * characters are spaces, in which case they're truncated. (per SQL)
121 bpchar_input(const char *s, size_t len, int32 atttypmod)
127 /* If typmod is -1 (or invalid), use the actual string length */
128 if (atttypmod < (int32) VARHDRSZ)
132 size_t charlen; /* number of CHARACTERS in the input */
134 maxlen = atttypmod - VARHDRSZ;
135 charlen = pg_mbstrlen_with_len(s, len);
136 if (charlen > maxlen)
138 /* Verify that extra characters are spaces, and clip them off */
139 size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
143 * at this point, len is the actual BYTE length of the input
144 * string, maxlen is the max number of CHARACTERS allowed for this
145 * bpchar type, mbmaxlen is the length in BYTES of those chars.
147 for (j = mbmaxlen; j < len; j++)
151 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
152 errmsg("value too long for type character(%d)",
157 * Now we set maxlen to the necessary byte length, not the number
160 maxlen = len = mbmaxlen;
165 * Now we set maxlen to the necessary byte length, not the number
168 maxlen = len + (maxlen - charlen);
172 result = (BpChar *) palloc(maxlen + VARHDRSZ);
173 SET_VARSIZE(result, maxlen + VARHDRSZ);
177 /* blank pad the string if necessary */
179 memset(r + len, ' ', maxlen - len);
185 * Convert a C string to CHARACTER internal representation. atttypmod
186 * is the declared length of the type plus VARHDRSZ.
189 bpcharin(PG_FUNCTION_ARGS)
191 char *s = PG_GETARG_CSTRING(0);
194 Oid typelem = PG_GETARG_OID(1);
196 int32 atttypmod = PG_GETARG_INT32(2);
199 result = bpchar_input(s, strlen(s), atttypmod);
200 PG_RETURN_BPCHAR_P(result);
205 * Convert a CHARACTER value to a C string.
207 * Uses the text conversion functions, which is only appropriate if BpChar
208 * and text are equivalent types.
211 bpcharout(PG_FUNCTION_ARGS)
213 Datum txt = PG_GETARG_DATUM(0);
215 PG_RETURN_CSTRING(TextDatumGetCString(txt));
219 * bpcharrecv - converts external binary format to bpchar
222 bpcharrecv(PG_FUNCTION_ARGS)
224 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
227 Oid typelem = PG_GETARG_OID(1);
229 int32 atttypmod = PG_GETARG_INT32(2);
234 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
235 result = bpchar_input(str, nbytes, atttypmod);
237 PG_RETURN_BPCHAR_P(result);
241 * bpcharsend - converts bpchar to binary format
244 bpcharsend(PG_FUNCTION_ARGS)
246 /* Exactly the same as textsend, so share code */
247 return textsend(fcinfo);
252 * Converts a CHARACTER type to the specified size.
254 * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
255 * isExplicit is true if this is for an explicit cast to char(N).
257 * Truncation rules: for an explicit cast, silently truncate to the given
258 * length; for an implicit cast, raise error unless extra characters are
259 * all spaces. (This is sort-of per SQL: the spec would actually have us
260 * raise a "completion condition" for the explicit cast case, but Postgres
261 * hasn't got such a concept.)
264 bpchar(PG_FUNCTION_ARGS)
266 BpChar *source = PG_GETARG_BPCHAR_PP(0);
267 int32 maxlen = PG_GETARG_INT32(1);
268 bool isExplicit = PG_GETARG_BOOL(2);
274 int charlen; /* number of characters in the input string +
277 /* No work if typmod is invalid */
278 if (maxlen < (int32) VARHDRSZ)
279 PG_RETURN_BPCHAR_P(source);
283 len = VARSIZE_ANY_EXHDR(source);
284 s = VARDATA_ANY(source);
286 charlen = pg_mbstrlen_with_len(s, len);
288 /* No work if supplied data matches typmod already */
289 if (charlen == maxlen)
290 PG_RETURN_BPCHAR_P(source);
292 if (charlen > maxlen)
294 /* Verify that extra characters are spaces, and clip them off */
297 maxmblen = pg_mbcharcliplen(s, len, maxlen);
301 for (i = maxmblen; i < len; i++)
304 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
305 errmsg("value too long for type character(%d)",
312 * At this point, maxlen is the necessary byte length, not the number
320 * At this point, maxlen is the necessary byte length, not the number
323 maxlen = len + (maxlen - charlen);
326 Assert(maxlen >= len);
328 result = palloc(maxlen + VARHDRSZ);
329 SET_VARSIZE(result, maxlen + VARHDRSZ);
334 /* blank pad the string if necessary */
336 memset(r + len, ' ', maxlen - len);
338 PG_RETURN_BPCHAR_P(result);
343 * Convert char to bpchar(1).
346 char_bpchar(PG_FUNCTION_ARGS)
348 char c = PG_GETARG_CHAR(0);
351 result = (BpChar *) palloc(VARHDRSZ + 1);
353 SET_VARSIZE(result, VARHDRSZ + 1);
354 *(VARDATA(result)) = c;
356 PG_RETURN_BPCHAR_P(result);
361 * Converts a bpchar() type to a NameData type.
364 bpchar_name(PG_FUNCTION_ARGS)
366 BpChar *s = PG_GETARG_BPCHAR_PP(0);
371 len = VARSIZE_ANY_EXHDR(s);
372 s_data = VARDATA_ANY(s);
374 /* Truncate to max length for a Name */
375 if (len >= NAMEDATALEN)
376 len = NAMEDATALEN - 1;
378 /* Remove trailing blanks */
381 if (s_data[len - 1] != ' ')
386 result = (NameData *) palloc(NAMEDATALEN);
387 memcpy(NameStr(*result), s_data, len);
389 /* Now null pad to full length... */
390 while (len < NAMEDATALEN)
392 *(NameStr(*result) + len) = '\0';
396 PG_RETURN_NAME(result);
400 * Converts a NameData type to a bpchar type.
402 * Uses the text conversion functions, which is only appropriate if BpChar
403 * and text are equivalent types.
406 name_bpchar(PG_FUNCTION_ARGS)
408 Name s = PG_GETARG_NAME(0);
411 result = (BpChar *) cstring_to_text(NameStr(*s));
412 PG_RETURN_BPCHAR_P(result);
416 bpchartypmodin(PG_FUNCTION_ARGS)
418 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
420 PG_RETURN_INT32(anychar_typmodin(ta, "char"));
424 bpchartypmodout(PG_FUNCTION_ARGS)
426 int32 typmod = PG_GETARG_INT32(0);
428 PG_RETURN_CSTRING(anychar_typmodout(typmod));
432 /*****************************************************************************
433 * varchar - varchar(n)
435 * Note: varchar piggybacks on type text for most operations, and so has no
436 * C-coded functions except for I/O and typmod checking.
437 *****************************************************************************/
440 * varchar_input -- common guts of varcharin and varcharrecv
442 * s is the input text of length len (may not be null-terminated)
443 * atttypmod is the typmod value to apply
445 * Note that atttypmod is measured in characters, which
446 * is not necessarily the same as the number of bytes.
448 * If the input string is too long, raise an error, unless the extra
449 * characters are spaces, in which case they're truncated. (per SQL)
451 * Uses the C string to text conversion function, which is only appropriate
452 * if VarChar and text are equivalent types.
455 varchar_input(const char *s, size_t len, int32 atttypmod)
460 maxlen = atttypmod - VARHDRSZ;
462 if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
464 /* Verify that extra characters are spaces, and clip them off */
465 size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
468 for (j = mbmaxlen; j < len; j++)
472 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
473 errmsg("value too long for type character varying(%d)",
480 result = (VarChar *) cstring_to_text_with_len(s, len);
485 * Convert a C string to VARCHAR internal representation. atttypmod
486 * is the declared length of the type plus VARHDRSZ.
489 varcharin(PG_FUNCTION_ARGS)
491 char *s = PG_GETARG_CSTRING(0);
494 Oid typelem = PG_GETARG_OID(1);
496 int32 atttypmod = PG_GETARG_INT32(2);
499 result = varchar_input(s, strlen(s), atttypmod);
500 PG_RETURN_VARCHAR_P(result);
505 * Convert a VARCHAR value to a C string.
507 * Uses the text to C string conversion function, which is only appropriate
508 * if VarChar and text are equivalent types.
511 varcharout(PG_FUNCTION_ARGS)
513 Datum txt = PG_GETARG_DATUM(0);
515 PG_RETURN_CSTRING(TextDatumGetCString(txt));
519 * varcharrecv - converts external binary format to varchar
522 varcharrecv(PG_FUNCTION_ARGS)
524 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
527 Oid typelem = PG_GETARG_OID(1);
529 int32 atttypmod = PG_GETARG_INT32(2);
534 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
535 result = varchar_input(str, nbytes, atttypmod);
537 PG_RETURN_VARCHAR_P(result);
541 * varcharsend - converts varchar to binary format
544 varcharsend(PG_FUNCTION_ARGS)
546 /* Exactly the same as textsend, so share code */
547 return textsend(fcinfo);
552 * Converts a VARCHAR type to the specified size.
554 * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
555 * isExplicit is true if this is for an explicit cast to varchar(N).
557 * Truncation rules: for an explicit cast, silently truncate to the given
558 * length; for an implicit cast, raise error unless extra characters are
559 * all spaces. (This is sort-of per SQL: the spec would actually have us
560 * raise a "completion condition" for the explicit cast case, but Postgres
561 * hasn't got such a concept.)
564 varchar(PG_FUNCTION_ARGS)
566 VarChar *source = PG_GETARG_VARCHAR_PP(0);
567 int32 typmod = PG_GETARG_INT32(1);
568 bool isExplicit = PG_GETARG_BOOL(2);
575 len = VARSIZE_ANY_EXHDR(source);
576 s_data = VARDATA_ANY(source);
577 maxlen = typmod - VARHDRSZ;
579 /* No work if typmod is invalid or supplied data fits it already */
580 if (maxlen < 0 || len <= maxlen)
581 PG_RETURN_VARCHAR_P(source);
583 /* only reach here if string is too long... */
585 /* truncate multibyte string preserving multibyte boundary */
586 maxmblen = pg_mbcharcliplen(s_data, len, maxlen);
590 for (i = maxmblen; i < len; i++)
591 if (s_data[i] != ' ')
593 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
594 errmsg("value too long for type character varying(%d)",
598 PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,
603 varchartypmodin(PG_FUNCTION_ARGS)
605 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
607 PG_RETURN_INT32(anychar_typmodin(ta, "varchar"));
611 varchartypmodout(PG_FUNCTION_ARGS)
613 int32 typmod = PG_GETARG_INT32(0);
615 PG_RETURN_CSTRING(anychar_typmodout(typmod));
619 /*****************************************************************************
621 *****************************************************************************/
623 /* "True" length (not counting trailing blanks) of a BpChar */
625 bcTruelen(BpChar *arg)
627 char *s = VARDATA_ANY(arg);
631 len = VARSIZE_ANY_EXHDR(arg);
632 for (i = len - 1; i >= 0; i--)
641 bpcharlen(PG_FUNCTION_ARGS)
643 BpChar *arg = PG_GETARG_BPCHAR_PP(0);
646 /* get number of bytes, ignoring trailing spaces */
647 len = bcTruelen(arg);
649 /* in multibyte encoding, convert to number of characters */
650 if (pg_database_encoding_max_length() != 1)
651 len = pg_mbstrlen_with_len(VARDATA_ANY(arg), len);
653 PG_RETURN_INT32(len);
657 bpcharoctetlen(PG_FUNCTION_ARGS)
659 Datum arg = PG_GETARG_DATUM(0);
661 /* We need not detoast the input at all */
662 PG_RETURN_INT32(toast_raw_datum_size(arg) - VARHDRSZ);
666 /*****************************************************************************
667 * Comparison Functions used for bpchar
669 * Note: btree indexes need these routines not to leak memory; therefore,
670 * be careful to free working copies of toasted datums. Most places don't
671 * need to be so careful.
672 *****************************************************************************/
675 bpchareq(PG_FUNCTION_ARGS)
677 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
678 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
683 len1 = bcTruelen(arg1);
684 len2 = bcTruelen(arg2);
687 * Since we only care about equality or not-equality, we can avoid all the
688 * expense of strcoll() here, and just do bitwise comparison.
693 result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
695 PG_FREE_IF_COPY(arg1, 0);
696 PG_FREE_IF_COPY(arg2, 1);
698 PG_RETURN_BOOL(result);
702 bpcharne(PG_FUNCTION_ARGS)
704 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
705 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
710 len1 = bcTruelen(arg1);
711 len2 = bcTruelen(arg2);
714 * Since we only care about equality or not-equality, we can avoid all the
715 * expense of strcoll() here, and just do bitwise comparison.
720 result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
722 PG_FREE_IF_COPY(arg1, 0);
723 PG_FREE_IF_COPY(arg2, 1);
725 PG_RETURN_BOOL(result);
729 bpcharlt(PG_FUNCTION_ARGS)
731 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
732 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
737 len1 = bcTruelen(arg1);
738 len2 = bcTruelen(arg2);
740 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
742 PG_FREE_IF_COPY(arg1, 0);
743 PG_FREE_IF_COPY(arg2, 1);
745 PG_RETURN_BOOL(cmp < 0);
749 bpcharle(PG_FUNCTION_ARGS)
751 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
752 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
757 len1 = bcTruelen(arg1);
758 len2 = bcTruelen(arg2);
760 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
762 PG_FREE_IF_COPY(arg1, 0);
763 PG_FREE_IF_COPY(arg2, 1);
765 PG_RETURN_BOOL(cmp <= 0);
769 bpchargt(PG_FUNCTION_ARGS)
771 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
772 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
777 len1 = bcTruelen(arg1);
778 len2 = bcTruelen(arg2);
780 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
782 PG_FREE_IF_COPY(arg1, 0);
783 PG_FREE_IF_COPY(arg2, 1);
785 PG_RETURN_BOOL(cmp > 0);
789 bpcharge(PG_FUNCTION_ARGS)
791 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
792 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
797 len1 = bcTruelen(arg1);
798 len2 = bcTruelen(arg2);
800 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
802 PG_FREE_IF_COPY(arg1, 0);
803 PG_FREE_IF_COPY(arg2, 1);
805 PG_RETURN_BOOL(cmp >= 0);
809 bpcharcmp(PG_FUNCTION_ARGS)
811 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
812 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
817 len1 = bcTruelen(arg1);
818 len2 = bcTruelen(arg2);
820 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
822 PG_FREE_IF_COPY(arg1, 0);
823 PG_FREE_IF_COPY(arg2, 1);
825 PG_RETURN_INT32(cmp);
829 bpchar_larger(PG_FUNCTION_ARGS)
831 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
832 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
837 len1 = bcTruelen(arg1);
838 len2 = bcTruelen(arg2);
840 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
842 PG_RETURN_BPCHAR_P((cmp >= 0) ? arg1 : arg2);
846 bpchar_smaller(PG_FUNCTION_ARGS)
848 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
849 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
854 len1 = bcTruelen(arg1);
855 len2 = bcTruelen(arg2);
857 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);
859 PG_RETURN_BPCHAR_P((cmp <= 0) ? arg1 : arg2);
864 * bpchar needs a specialized hash function because we want to ignore
865 * trailing blanks in comparisons.
867 * Note: currently there is no need for locale-specific behavior here,
868 * but if we ever change the semantics of bpchar comparison to trust
869 * strcoll() completely, we'd need to do something different in non-C locales.
872 hashbpchar(PG_FUNCTION_ARGS)
874 BpChar *key = PG_GETARG_BPCHAR_PP(0);
879 keydata = VARDATA_ANY(key);
880 keylen = bcTruelen(key);
882 result = hash_any((unsigned char *) keydata, keylen);
884 /* Avoid leaking memory for toasted inputs */
885 PG_FREE_IF_COPY(key, 0);
892 * The following operators support character-by-character comparison
893 * of bpchar datums, to allow building indexes suitable for LIKE clauses.
894 * Note that the regular bpchareq/bpcharne comparison operators are assumed
895 * to be compatible with these!
899 internal_bpchar_pattern_compare(BpChar *arg1, BpChar *arg2)
905 len1 = bcTruelen(arg1);
906 len2 = bcTruelen(arg2);
908 result = strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
911 else if (len1 < len2)
913 else if (len1 > len2)
921 bpchar_pattern_lt(PG_FUNCTION_ARGS)
923 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
924 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
927 result = internal_bpchar_pattern_compare(arg1, arg2);
929 PG_FREE_IF_COPY(arg1, 0);
930 PG_FREE_IF_COPY(arg2, 1);
932 PG_RETURN_BOOL(result < 0);
937 bpchar_pattern_le(PG_FUNCTION_ARGS)
939 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
940 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
943 result = internal_bpchar_pattern_compare(arg1, arg2);
945 PG_FREE_IF_COPY(arg1, 0);
946 PG_FREE_IF_COPY(arg2, 1);
948 PG_RETURN_BOOL(result <= 0);
953 bpchar_pattern_ge(PG_FUNCTION_ARGS)
955 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
956 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
959 result = internal_bpchar_pattern_compare(arg1, arg2);
961 PG_FREE_IF_COPY(arg1, 0);
962 PG_FREE_IF_COPY(arg2, 1);
964 PG_RETURN_BOOL(result >= 0);
969 bpchar_pattern_gt(PG_FUNCTION_ARGS)
971 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
972 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
975 result = internal_bpchar_pattern_compare(arg1, arg2);
977 PG_FREE_IF_COPY(arg1, 0);
978 PG_FREE_IF_COPY(arg2, 1);
980 PG_RETURN_BOOL(result > 0);
985 btbpchar_pattern_cmp(PG_FUNCTION_ARGS)
987 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
988 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
991 result = internal_bpchar_pattern_compare(arg1, arg2);
993 PG_FREE_IF_COPY(arg1, 0);
994 PG_FREE_IF_COPY(arg2, 1);
996 PG_RETURN_INT32(result);