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