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