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