]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/varchar.c
Move some things from builtins.h to new header files
[postgresql] / src / backend / utils / adt / varchar.c
1 /*-------------------------------------------------------------------------
2  *
3  * varchar.c
4  *        Functions for the built-in types char(n) and varchar(n).
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        src/backend/utils/adt/varchar.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17
18 #include "access/hash.h"
19 #include "access/tuptoaster.h"
20 #include "catalog/pg_collation.h"
21 #include "libpq/pqformat.h"
22 #include "nodes/nodeFuncs.h"
23 #include "utils/array.h"
24 #include "utils/builtins.h"
25 #include "utils/varlena.h"
26 #include "mb/pg_wchar.h"
27
28
29 /* common code for bpchartypmodin and varchartypmodin */
30 static int32
31 anychar_typmodin(ArrayType *ta, const char *typename)
32 {
33         int32           typmod;
34         int32      *tl;
35         int                     n;
36
37         tl = ArrayGetIntegerTypmods(ta, &n);
38
39         /*
40          * we're not too tense about good error message here because grammar
41          * shouldn't allow wrong number of modifiers for CHAR
42          */
43         if (n != 1)
44                 ereport(ERROR,
45                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
46                                  errmsg("invalid type modifier")));
47
48         if (*tl < 1)
49                 ereport(ERROR,
50                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
51                                  errmsg("length for type %s must be at least 1", typename)));
52         if (*tl > MaxAttrSize)
53                 ereport(ERROR,
54                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
55                                  errmsg("length for type %s cannot exceed %d",
56                                                 typename, MaxAttrSize)));
57
58         /*
59          * For largely historical reasons, the typmod is VARHDRSZ plus the number
60          * of characters; there is enough client-side code that knows about that
61          * that we'd better not change it.
62          */
63         typmod = VARHDRSZ + *tl;
64
65         return typmod;
66 }
67
68 /* common code for bpchartypmodout and varchartypmodout */
69 static char *
70 anychar_typmodout(int32 typmod)
71 {
72         char       *res = (char *) palloc(64);
73
74         if (typmod > VARHDRSZ)
75                 snprintf(res, 64, "(%d)", (int) (typmod - VARHDRSZ));
76         else
77                 *res = '\0';
78
79         return res;
80 }
81
82
83 /*
84  * CHAR() and VARCHAR() types are part of the SQL standard. CHAR()
85  * is for blank-padded string whose length is specified in CREATE TABLE.
86  * VARCHAR is for storing string whose length is at most the length specified
87  * at CREATE TABLE time.
88  *
89  * It's hard to implement these types because we cannot figure out
90  * the length of the type from the type itself. I changed (hopefully all) the
91  * fmgr calls that invoke input functions of a data type to supply the
92  * length also. (eg. in INSERTs, we have the tupleDescriptor which contains
93  * the length of the attributes and hence the exact length of the char() or
94  * varchar(). We pass this to bpcharin() or varcharin().) In the case where
95  * we cannot determine the length, we pass in -1 instead and the input
96  * converter does not enforce any length check.
97  *
98  * We actually implement this as a varlena so that we don't have to pass in
99  * the length for the comparison functions. (The difference between these
100  * types and "text" is that we truncate and possibly blank-pad the string
101  * at insertion time.)
102  *
103  *                                                                                                                        - ay 6/95
104  */
105
106
107 /*****************************************************************************
108  *       bpchar - char()                                                                                                                 *
109  *****************************************************************************/
110
111 /*
112  * bpchar_input -- common guts of bpcharin and bpcharrecv
113  *
114  * s is the input text of length len (may not be null-terminated)
115  * atttypmod is the typmod value to apply
116  *
117  * Note that atttypmod is measured in characters, which
118  * is not necessarily the same as the number of bytes.
119  *
120  * If the input string is too long, raise an error, unless the extra
121  * characters are spaces, in which case they're truncated.  (per SQL)
122  */
123 static BpChar *
124 bpchar_input(const char *s, size_t len, int32 atttypmod)
125 {
126         BpChar     *result;
127         char       *r;
128         size_t          maxlen;
129
130         /* If typmod is -1 (or invalid), use the actual string length */
131         if (atttypmod < (int32) VARHDRSZ)
132                 maxlen = len;
133         else
134         {
135                 size_t          charlen;        /* number of CHARACTERS in the input */
136
137                 maxlen = atttypmod - VARHDRSZ;
138                 charlen = pg_mbstrlen_with_len(s, len);
139                 if (charlen > maxlen)
140                 {
141                         /* Verify that extra characters are spaces, and clip them off */
142                         size_t          mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
143                         size_t          j;
144
145                         /*
146                          * at this point, len is the actual BYTE length of the input
147                          * string, maxlen is the max number of CHARACTERS allowed for this
148                          * bpchar type, mbmaxlen is the length in BYTES of those chars.
149                          */
150                         for (j = mbmaxlen; j < len; j++)
151                         {
152                                 if (s[j] != ' ')
153                                         ereport(ERROR,
154                                                         (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
155                                                          errmsg("value too long for type character(%d)",
156                                                                         (int) maxlen)));
157                         }
158
159                         /*
160                          * Now we set maxlen to the necessary byte length, not the number
161                          * of CHARACTERS!
162                          */
163                         maxlen = len = mbmaxlen;
164                 }
165                 else
166                 {
167                         /*
168                          * Now we set maxlen to the necessary byte length, not the number
169                          * of CHARACTERS!
170                          */
171                         maxlen = len + (maxlen - charlen);
172                 }
173         }
174
175         result = (BpChar *) palloc(maxlen + VARHDRSZ);
176         SET_VARSIZE(result, maxlen + VARHDRSZ);
177         r = VARDATA(result);
178         memcpy(r, s, len);
179
180         /* blank pad the string if necessary */
181         if (maxlen > len)
182                 memset(r + len, ' ', maxlen - len);
183
184         return result;
185 }
186
187 /*
188  * Convert a C string to CHARACTER internal representation.  atttypmod
189  * is the declared length of the type plus VARHDRSZ.
190  */
191 Datum
192 bpcharin(PG_FUNCTION_ARGS)
193 {
194         char       *s = PG_GETARG_CSTRING(0);
195
196 #ifdef NOT_USED
197         Oid                     typelem = PG_GETARG_OID(1);
198 #endif
199         int32           atttypmod = PG_GETARG_INT32(2);
200         BpChar     *result;
201
202         result = bpchar_input(s, strlen(s), atttypmod);
203         PG_RETURN_BPCHAR_P(result);
204 }
205
206
207 /*
208  * Convert a CHARACTER value to a C string.
209  *
210  * Uses the text conversion functions, which is only appropriate if BpChar
211  * and text are equivalent types.
212  */
213 Datum
214 bpcharout(PG_FUNCTION_ARGS)
215 {
216         Datum           txt = PG_GETARG_DATUM(0);
217
218         PG_RETURN_CSTRING(TextDatumGetCString(txt));
219 }
220
221 /*
222  *              bpcharrecv                      - converts external binary format to bpchar
223  */
224 Datum
225 bpcharrecv(PG_FUNCTION_ARGS)
226 {
227         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
228
229 #ifdef NOT_USED
230         Oid                     typelem = PG_GETARG_OID(1);
231 #endif
232         int32           atttypmod = PG_GETARG_INT32(2);
233         BpChar     *result;
234         char       *str;
235         int                     nbytes;
236
237         str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
238         result = bpchar_input(str, nbytes, atttypmod);
239         pfree(str);
240         PG_RETURN_BPCHAR_P(result);
241 }
242
243 /*
244  *              bpcharsend                      - converts bpchar to binary format
245  */
246 Datum
247 bpcharsend(PG_FUNCTION_ARGS)
248 {
249         /* Exactly the same as textsend, so share code */
250         return textsend(fcinfo);
251 }
252
253
254 /*
255  * Converts a CHARACTER type to the specified size.
256  *
257  * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
258  * isExplicit is true if this is for an explicit cast to char(N).
259  *
260  * Truncation rules: for an explicit cast, silently truncate to the given
261  * length; for an implicit cast, raise error unless extra characters are
262  * all spaces.  (This is sort-of per SQL: the spec would actually have us
263  * raise a "completion condition" for the explicit cast case, but Postgres
264  * hasn't got such a concept.)
265  */
266 Datum
267 bpchar(PG_FUNCTION_ARGS)
268 {
269         BpChar     *source = PG_GETARG_BPCHAR_PP(0);
270         int32           maxlen = PG_GETARG_INT32(1);
271         bool            isExplicit = PG_GETARG_BOOL(2);
272         BpChar     *result;
273         int32           len;
274         char       *r;
275         char       *s;
276         int                     i;
277         int                     charlen;                /* number of characters in the input string +
278                                                                  * VARHDRSZ */
279
280         /* No work if typmod is invalid */
281         if (maxlen < (int32) VARHDRSZ)
282                 PG_RETURN_BPCHAR_P(source);
283
284         maxlen -= VARHDRSZ;
285
286         len = VARSIZE_ANY_EXHDR(source);
287         s = VARDATA_ANY(source);
288
289         charlen = pg_mbstrlen_with_len(s, len);
290
291         /* No work if supplied data matches typmod already */
292         if (charlen == maxlen)
293                 PG_RETURN_BPCHAR_P(source);
294
295         if (charlen > maxlen)
296         {
297                 /* Verify that extra characters are spaces, and clip them off */
298                 size_t          maxmblen;
299
300                 maxmblen = pg_mbcharcliplen(s, len, maxlen);
301
302                 if (!isExplicit)
303                 {
304                         for (i = maxmblen; i < len; i++)
305                                 if (s[i] != ' ')
306                                         ereport(ERROR,
307                                                         (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
308                                                          errmsg("value too long for type character(%d)",
309                                                                         maxlen)));
310                 }
311
312                 len = maxmblen;
313
314                 /*
315                  * At this point, maxlen is the necessary byte length, not the number
316                  * of CHARACTERS!
317                  */
318                 maxlen = len;
319         }
320         else
321         {
322                 /*
323                  * At this point, maxlen is the necessary byte length, not the number
324                  * of CHARACTERS!
325                  */
326                 maxlen = len + (maxlen - charlen);
327         }
328
329         Assert(maxlen >= len);
330
331         result = palloc(maxlen + VARHDRSZ);
332         SET_VARSIZE(result, maxlen + VARHDRSZ);
333         r = VARDATA(result);
334
335         memcpy(r, s, len);
336
337         /* blank pad the string if necessary */
338         if (maxlen > len)
339                 memset(r + len, ' ', maxlen - len);
340
341         PG_RETURN_BPCHAR_P(result);
342 }
343
344
345 /* char_bpchar()
346  * Convert char to bpchar(1).
347  */
348 Datum
349 char_bpchar(PG_FUNCTION_ARGS)
350 {
351         char            c = PG_GETARG_CHAR(0);
352         BpChar     *result;
353
354         result = (BpChar *) palloc(VARHDRSZ + 1);
355
356         SET_VARSIZE(result, VARHDRSZ + 1);
357         *(VARDATA(result)) = c;
358
359         PG_RETURN_BPCHAR_P(result);
360 }
361
362
363 /* bpchar_name()
364  * Converts a bpchar() type to a NameData type.
365  */
366 Datum
367 bpchar_name(PG_FUNCTION_ARGS)
368 {
369         BpChar     *s = PG_GETARG_BPCHAR_PP(0);
370         char       *s_data;
371         Name            result;
372         int                     len;
373
374         len = VARSIZE_ANY_EXHDR(s);
375         s_data = VARDATA_ANY(s);
376
377         /* Truncate oversize input */
378         if (len >= NAMEDATALEN)
379                 len = pg_mbcliplen(s_data, len, NAMEDATALEN - 1);
380
381         /* Remove trailing blanks */
382         while (len > 0)
383         {
384                 if (s_data[len - 1] != ' ')
385                         break;
386                 len--;
387         }
388
389         /* We use palloc0 here to ensure result is zero-padded */
390         result = (Name) palloc0(NAMEDATALEN);
391         memcpy(NameStr(*result), s_data, len);
392
393         PG_RETURN_NAME(result);
394 }
395
396 /* name_bpchar()
397  * Converts a NameData type to a bpchar type.
398  *
399  * Uses the text conversion functions, which is only appropriate if BpChar
400  * and text are equivalent types.
401  */
402 Datum
403 name_bpchar(PG_FUNCTION_ARGS)
404 {
405         Name            s = PG_GETARG_NAME(0);
406         BpChar     *result;
407
408         result = (BpChar *) cstring_to_text(NameStr(*s));
409         PG_RETURN_BPCHAR_P(result);
410 }
411
412 Datum
413 bpchartypmodin(PG_FUNCTION_ARGS)
414 {
415         ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
416
417         PG_RETURN_INT32(anychar_typmodin(ta, "char"));
418 }
419
420 Datum
421 bpchartypmodout(PG_FUNCTION_ARGS)
422 {
423         int32           typmod = PG_GETARG_INT32(0);
424
425         PG_RETURN_CSTRING(anychar_typmodout(typmod));
426 }
427
428
429 /*****************************************************************************
430  *       varchar - varchar(n)
431  *
432  * Note: varchar piggybacks on type text for most operations, and so has no
433  * C-coded functions except for I/O and typmod checking.
434  *****************************************************************************/
435
436 /*
437  * varchar_input -- common guts of varcharin and varcharrecv
438  *
439  * s is the input text of length len (may not be null-terminated)
440  * atttypmod is the typmod value to apply
441  *
442  * Note that atttypmod is measured in characters, which
443  * is not necessarily the same as the number of bytes.
444  *
445  * If the input string is too long, raise an error, unless the extra
446  * characters are spaces, in which case they're truncated.  (per SQL)
447  *
448  * Uses the C string to text conversion function, which is only appropriate
449  * if VarChar and text are equivalent types.
450  */
451 static VarChar *
452 varchar_input(const char *s, size_t len, int32 atttypmod)
453 {
454         VarChar    *result;
455         size_t          maxlen;
456
457         maxlen = atttypmod - VARHDRSZ;
458
459         if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
460         {
461                 /* Verify that extra characters are spaces, and clip them off */
462                 size_t          mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
463                 size_t          j;
464
465                 for (j = mbmaxlen; j < len; j++)
466                 {
467                         if (s[j] != ' ')
468                                 ereport(ERROR,
469                                                 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
470                                           errmsg("value too long for type character varying(%d)",
471                                                          (int) maxlen)));
472                 }
473
474                 len = mbmaxlen;
475         }
476
477         result = (VarChar *) cstring_to_text_with_len(s, len);
478         return result;
479 }
480
481 /*
482  * Convert a C string to VARCHAR internal representation.  atttypmod
483  * is the declared length of the type plus VARHDRSZ.
484  */
485 Datum
486 varcharin(PG_FUNCTION_ARGS)
487 {
488         char       *s = PG_GETARG_CSTRING(0);
489
490 #ifdef NOT_USED
491         Oid                     typelem = PG_GETARG_OID(1);
492 #endif
493         int32           atttypmod = PG_GETARG_INT32(2);
494         VarChar    *result;
495
496         result = varchar_input(s, strlen(s), atttypmod);
497         PG_RETURN_VARCHAR_P(result);
498 }
499
500
501 /*
502  * Convert a VARCHAR value to a C string.
503  *
504  * Uses the text to C string conversion function, which is only appropriate
505  * if VarChar and text are equivalent types.
506  */
507 Datum
508 varcharout(PG_FUNCTION_ARGS)
509 {
510         Datum           txt = PG_GETARG_DATUM(0);
511
512         PG_RETURN_CSTRING(TextDatumGetCString(txt));
513 }
514
515 /*
516  *              varcharrecv                     - converts external binary format to varchar
517  */
518 Datum
519 varcharrecv(PG_FUNCTION_ARGS)
520 {
521         StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
522
523 #ifdef NOT_USED
524         Oid                     typelem = PG_GETARG_OID(1);
525 #endif
526         int32           atttypmod = PG_GETARG_INT32(2);
527         VarChar    *result;
528         char       *str;
529         int                     nbytes;
530
531         str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
532         result = varchar_input(str, nbytes, atttypmod);
533         pfree(str);
534         PG_RETURN_VARCHAR_P(result);
535 }
536
537 /*
538  *              varcharsend                     - converts varchar to binary format
539  */
540 Datum
541 varcharsend(PG_FUNCTION_ARGS)
542 {
543         /* Exactly the same as textsend, so share code */
544         return textsend(fcinfo);
545 }
546
547
548 /*
549  * varchar_transform()
550  * Flatten calls to varchar's length coercion function that set the new maximum
551  * length >= the previous maximum length.  We can ignore the isExplicit
552  * argument, since that only affects truncation cases.
553  */
554 Datum
555 varchar_transform(PG_FUNCTION_ARGS)
556 {
557         FuncExpr   *expr = (FuncExpr *) PG_GETARG_POINTER(0);
558         Node       *ret = NULL;
559         Node       *typmod;
560
561         Assert(IsA(expr, FuncExpr));
562         Assert(list_length(expr->args) >= 2);
563
564         typmod = (Node *) lsecond(expr->args);
565
566         if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull)
567         {
568                 Node       *source = (Node *) linitial(expr->args);
569                 int32           old_typmod = exprTypmod(source);
570                 int32           new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
571                 int32           old_max = old_typmod - VARHDRSZ;
572                 int32           new_max = new_typmod - VARHDRSZ;
573
574                 if (new_typmod < 0 || (old_typmod >= 0 && old_max <= new_max))
575                         ret = relabel_to_typmod(source, new_typmod);
576         }
577
578         PG_RETURN_POINTER(ret);
579 }
580
581 /*
582  * Converts a VARCHAR type to the specified size.
583  *
584  * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes.
585  * isExplicit is true if this is for an explicit cast to varchar(N).
586  *
587  * Truncation rules: for an explicit cast, silently truncate to the given
588  * length; for an implicit cast, raise error unless extra characters are
589  * all spaces.  (This is sort-of per SQL: the spec would actually have us
590  * raise a "completion condition" for the explicit cast case, but Postgres
591  * hasn't got such a concept.)
592  */
593 Datum
594 varchar(PG_FUNCTION_ARGS)
595 {
596         VarChar    *source = PG_GETARG_VARCHAR_PP(0);
597         int32           typmod = PG_GETARG_INT32(1);
598         bool            isExplicit = PG_GETARG_BOOL(2);
599         int32           len,
600                                 maxlen;
601         size_t          maxmblen;
602         int                     i;
603         char       *s_data;
604
605         len = VARSIZE_ANY_EXHDR(source);
606         s_data = VARDATA_ANY(source);
607         maxlen = typmod - VARHDRSZ;
608
609         /* No work if typmod is invalid or supplied data fits it already */
610         if (maxlen < 0 || len <= maxlen)
611                 PG_RETURN_VARCHAR_P(source);
612
613         /* only reach here if string is too long... */
614
615         /* truncate multibyte string preserving multibyte boundary */
616         maxmblen = pg_mbcharcliplen(s_data, len, maxlen);
617
618         if (!isExplicit)
619         {
620                 for (i = maxmblen; i < len; i++)
621                         if (s_data[i] != ' ')
622                                 ereport(ERROR,
623                                                 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
624                                           errmsg("value too long for type character varying(%d)",
625                                                          maxlen)));
626         }
627
628         PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,
629                                                                                                                          maxmblen));
630 }
631
632 Datum
633 varchartypmodin(PG_FUNCTION_ARGS)
634 {
635         ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);
636
637         PG_RETURN_INT32(anychar_typmodin(ta, "varchar"));
638 }
639
640 Datum
641 varchartypmodout(PG_FUNCTION_ARGS)
642 {
643         int32           typmod = PG_GETARG_INT32(0);
644
645         PG_RETURN_CSTRING(anychar_typmodout(typmod));
646 }
647
648
649 /*****************************************************************************
650  * Exported functions
651  *****************************************************************************/
652
653 /* "True" length (not counting trailing blanks) of a BpChar */
654 static inline int
655 bcTruelen(BpChar *arg)
656 {
657         return bpchartruelen(VARDATA_ANY(arg), VARSIZE_ANY_EXHDR(arg));
658 }
659
660 int
661 bpchartruelen(char *s, int len)
662 {
663         int                     i;
664
665         /*
666          * Note that we rely on the assumption that ' ' is a singleton unit on
667          * every supported multibyte server encoding.
668          */
669         for (i = len - 1; i >= 0; i--)
670         {
671                 if (s[i] != ' ')
672                         break;
673         }
674         return i + 1;
675 }
676
677 Datum
678 bpcharlen(PG_FUNCTION_ARGS)
679 {
680         BpChar     *arg = PG_GETARG_BPCHAR_PP(0);
681         int                     len;
682
683         /* get number of bytes, ignoring trailing spaces */
684         len = bcTruelen(arg);
685
686         /* in multibyte encoding, convert to number of characters */
687         if (pg_database_encoding_max_length() != 1)
688                 len = pg_mbstrlen_with_len(VARDATA_ANY(arg), len);
689
690         PG_RETURN_INT32(len);
691 }
692
693 Datum
694 bpcharoctetlen(PG_FUNCTION_ARGS)
695 {
696         Datum           arg = PG_GETARG_DATUM(0);
697
698         /* We need not detoast the input at all */
699         PG_RETURN_INT32(toast_raw_datum_size(arg) - VARHDRSZ);
700 }
701
702
703 /*****************************************************************************
704  *      Comparison Functions used for bpchar
705  *
706  * Note: btree indexes need these routines not to leak memory; therefore,
707  * be careful to free working copies of toasted datums.  Most places don't
708  * need to be so careful.
709  *****************************************************************************/
710
711 Datum
712 bpchareq(PG_FUNCTION_ARGS)
713 {
714         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
715         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
716         int                     len1,
717                                 len2;
718         bool            result;
719
720         len1 = bcTruelen(arg1);
721         len2 = bcTruelen(arg2);
722
723         /*
724          * Since we only care about equality or not-equality, we can avoid all the
725          * expense of strcoll() here, and just do bitwise comparison.
726          */
727         if (len1 != len2)
728                 result = false;
729         else
730                 result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
731
732         PG_FREE_IF_COPY(arg1, 0);
733         PG_FREE_IF_COPY(arg2, 1);
734
735         PG_RETURN_BOOL(result);
736 }
737
738 Datum
739 bpcharne(PG_FUNCTION_ARGS)
740 {
741         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
742         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
743         int                     len1,
744                                 len2;
745         bool            result;
746
747         len1 = bcTruelen(arg1);
748         len2 = bcTruelen(arg2);
749
750         /*
751          * Since we only care about equality or not-equality, we can avoid all the
752          * expense of strcoll() here, and just do bitwise comparison.
753          */
754         if (len1 != len2)
755                 result = true;
756         else
757                 result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
758
759         PG_FREE_IF_COPY(arg1, 0);
760         PG_FREE_IF_COPY(arg2, 1);
761
762         PG_RETURN_BOOL(result);
763 }
764
765 Datum
766 bpcharlt(PG_FUNCTION_ARGS)
767 {
768         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
769         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
770         int                     len1,
771                                 len2;
772         int                     cmp;
773
774         len1 = bcTruelen(arg1);
775         len2 = bcTruelen(arg2);
776
777         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
778                                          PG_GET_COLLATION());
779
780         PG_FREE_IF_COPY(arg1, 0);
781         PG_FREE_IF_COPY(arg2, 1);
782
783         PG_RETURN_BOOL(cmp < 0);
784 }
785
786 Datum
787 bpcharle(PG_FUNCTION_ARGS)
788 {
789         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
790         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
791         int                     len1,
792                                 len2;
793         int                     cmp;
794
795         len1 = bcTruelen(arg1);
796         len2 = bcTruelen(arg2);
797
798         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
799                                          PG_GET_COLLATION());
800
801         PG_FREE_IF_COPY(arg1, 0);
802         PG_FREE_IF_COPY(arg2, 1);
803
804         PG_RETURN_BOOL(cmp <= 0);
805 }
806
807 Datum
808 bpchargt(PG_FUNCTION_ARGS)
809 {
810         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
811         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
812         int                     len1,
813                                 len2;
814         int                     cmp;
815
816         len1 = bcTruelen(arg1);
817         len2 = bcTruelen(arg2);
818
819         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
820                                          PG_GET_COLLATION());
821
822         PG_FREE_IF_COPY(arg1, 0);
823         PG_FREE_IF_COPY(arg2, 1);
824
825         PG_RETURN_BOOL(cmp > 0);
826 }
827
828 Datum
829 bpcharge(PG_FUNCTION_ARGS)
830 {
831         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
832         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
833         int                     len1,
834                                 len2;
835         int                     cmp;
836
837         len1 = bcTruelen(arg1);
838         len2 = bcTruelen(arg2);
839
840         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
841                                          PG_GET_COLLATION());
842
843         PG_FREE_IF_COPY(arg1, 0);
844         PG_FREE_IF_COPY(arg2, 1);
845
846         PG_RETURN_BOOL(cmp >= 0);
847 }
848
849 Datum
850 bpcharcmp(PG_FUNCTION_ARGS)
851 {
852         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
853         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
854         int                     len1,
855                                 len2;
856         int                     cmp;
857
858         len1 = bcTruelen(arg1);
859         len2 = bcTruelen(arg2);
860
861         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
862                                          PG_GET_COLLATION());
863
864         PG_FREE_IF_COPY(arg1, 0);
865         PG_FREE_IF_COPY(arg2, 1);
866
867         PG_RETURN_INT32(cmp);
868 }
869
870 Datum
871 bpchar_sortsupport(PG_FUNCTION_ARGS)
872 {
873         SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
874         Oid                     collid = ssup->ssup_collation;
875         MemoryContext oldcontext;
876
877         oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
878
879         /* Use generic string SortSupport */
880         varstr_sortsupport(ssup, collid, true);
881
882         MemoryContextSwitchTo(oldcontext);
883
884         PG_RETURN_VOID();
885 }
886
887 Datum
888 bpchar_larger(PG_FUNCTION_ARGS)
889 {
890         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
891         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
892         int                     len1,
893                                 len2;
894         int                     cmp;
895
896         len1 = bcTruelen(arg1);
897         len2 = bcTruelen(arg2);
898
899         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
900                                          PG_GET_COLLATION());
901
902         PG_RETURN_BPCHAR_P((cmp >= 0) ? arg1 : arg2);
903 }
904
905 Datum
906 bpchar_smaller(PG_FUNCTION_ARGS)
907 {
908         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
909         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
910         int                     len1,
911                                 len2;
912         int                     cmp;
913
914         len1 = bcTruelen(arg1);
915         len2 = bcTruelen(arg2);
916
917         cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
918                                          PG_GET_COLLATION());
919
920         PG_RETURN_BPCHAR_P((cmp <= 0) ? arg1 : arg2);
921 }
922
923
924 /*
925  * bpchar needs a specialized hash function because we want to ignore
926  * trailing blanks in comparisons.
927  *
928  * Note: currently there is no need for locale-specific behavior here,
929  * but if we ever change the semantics of bpchar comparison to trust
930  * strcoll() completely, we'd need to do something different in non-C locales.
931  */
932 Datum
933 hashbpchar(PG_FUNCTION_ARGS)
934 {
935         BpChar     *key = PG_GETARG_BPCHAR_PP(0);
936         char       *keydata;
937         int                     keylen;
938         Datum           result;
939
940         keydata = VARDATA_ANY(key);
941         keylen = bcTruelen(key);
942
943         result = hash_any((unsigned char *) keydata, keylen);
944
945         /* Avoid leaking memory for toasted inputs */
946         PG_FREE_IF_COPY(key, 0);
947
948         return result;
949 }
950
951
952 /*
953  * The following operators support character-by-character comparison
954  * of bpchar datums, to allow building indexes suitable for LIKE clauses.
955  * Note that the regular bpchareq/bpcharne comparison operators, and
956  * regular support functions 1 and 2 with "C" collation are assumed to be
957  * compatible with these!
958  */
959
960 static int
961 internal_bpchar_pattern_compare(BpChar *arg1, BpChar *arg2)
962 {
963         int                     result;
964         int                     len1,
965                                 len2;
966
967         len1 = bcTruelen(arg1);
968         len2 = bcTruelen(arg2);
969
970         result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
971         if (result != 0)
972                 return result;
973         else if (len1 < len2)
974                 return -1;
975         else if (len1 > len2)
976                 return 1;
977         else
978                 return 0;
979 }
980
981
982 Datum
983 bpchar_pattern_lt(PG_FUNCTION_ARGS)
984 {
985         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
986         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
987         int                     result;
988
989         result = internal_bpchar_pattern_compare(arg1, arg2);
990
991         PG_FREE_IF_COPY(arg1, 0);
992         PG_FREE_IF_COPY(arg2, 1);
993
994         PG_RETURN_BOOL(result < 0);
995 }
996
997
998 Datum
999 bpchar_pattern_le(PG_FUNCTION_ARGS)
1000 {
1001         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
1002         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
1003         int                     result;
1004
1005         result = internal_bpchar_pattern_compare(arg1, arg2);
1006
1007         PG_FREE_IF_COPY(arg1, 0);
1008         PG_FREE_IF_COPY(arg2, 1);
1009
1010         PG_RETURN_BOOL(result <= 0);
1011 }
1012
1013
1014 Datum
1015 bpchar_pattern_ge(PG_FUNCTION_ARGS)
1016 {
1017         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
1018         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
1019         int                     result;
1020
1021         result = internal_bpchar_pattern_compare(arg1, arg2);
1022
1023         PG_FREE_IF_COPY(arg1, 0);
1024         PG_FREE_IF_COPY(arg2, 1);
1025
1026         PG_RETURN_BOOL(result >= 0);
1027 }
1028
1029
1030 Datum
1031 bpchar_pattern_gt(PG_FUNCTION_ARGS)
1032 {
1033         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
1034         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
1035         int                     result;
1036
1037         result = internal_bpchar_pattern_compare(arg1, arg2);
1038
1039         PG_FREE_IF_COPY(arg1, 0);
1040         PG_FREE_IF_COPY(arg2, 1);
1041
1042         PG_RETURN_BOOL(result > 0);
1043 }
1044
1045
1046 Datum
1047 btbpchar_pattern_cmp(PG_FUNCTION_ARGS)
1048 {
1049         BpChar     *arg1 = PG_GETARG_BPCHAR_PP(0);
1050         BpChar     *arg2 = PG_GETARG_BPCHAR_PP(1);
1051         int                     result;
1052
1053         result = internal_bpchar_pattern_compare(arg1, arg2);
1054
1055         PG_FREE_IF_COPY(arg1, 0);
1056         PG_FREE_IF_COPY(arg2, 1);
1057
1058         PG_RETURN_INT32(result);
1059 }
1060
1061
1062 Datum
1063 btbpchar_pattern_sortsupport(PG_FUNCTION_ARGS)
1064 {
1065         SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
1066         MemoryContext oldcontext;
1067
1068         oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1069
1070         /* Use generic string SortSupport, forcing "C" collation */
1071         varstr_sortsupport(ssup, C_COLLATION_OID, true);
1072
1073         MemoryContextSwitchTo(oldcontext);
1074
1075         PG_RETURN_VOID();
1076 }