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