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