PostgreSQL Source Code  git master
varlena.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * varlena.c
4  * Functions for the variable-length built-in types.
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/varlena.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include <ctype.h>
18 #include <limits.h>
19 
20 #include "access/detoast.h"
22 #include "catalog/pg_collation.h"
23 #include "catalog/pg_type.h"
24 #include "common/hashfn.h"
25 #include "common/int.h"
27 #include "common/unicode_norm.h"
28 #include "common/unicode_version.h"
29 #include "funcapi.h"
30 #include "lib/hyperloglog.h"
31 #include "libpq/pqformat.h"
32 #include "miscadmin.h"
33 #include "nodes/execnodes.h"
34 #include "parser/scansup.h"
35 #include "port/pg_bswap.h"
36 #include "regex/regex.h"
37 #include "utils/builtins.h"
38 #include "utils/bytea.h"
39 #include "utils/guc.h"
40 #include "utils/lsyscache.h"
41 #include "utils/memutils.h"
42 #include "utils/pg_locale.h"
43 #include "utils/sortsupport.h"
44 #include "utils/varlena.h"
45 
46 
47 /* GUC variable */
49 
50 typedef struct varlena VarString;
51 
52 /*
53  * State for text_position_* functions.
54  */
55 typedef struct
56 {
57  bool is_multibyte_char_in_char; /* need to check char boundaries? */
58 
59  char *str1; /* haystack string */
60  char *str2; /* needle string */
61  int len1; /* string lengths in bytes */
62  int len2;
63 
64  /* Skip table for Boyer-Moore-Horspool search algorithm: */
65  int skiptablemask; /* mask for ANDing with skiptable subscripts */
66  int skiptable[256]; /* skip distance for given mismatched char */
67 
68  char *last_match; /* pointer to last match in 'str1' */
69 
70  /*
71  * Sometimes we need to convert the byte position of a match to a
72  * character position. These store the last position that was converted,
73  * so that on the next call, we can continue from that point, rather than
74  * count characters from the very beginning.
75  */
76  char *refpoint; /* pointer within original haystack string */
77  int refpos; /* 0-based character offset of the same point */
79 
80 typedef struct
81 {
82  char *buf1; /* 1st string, or abbreviation original string
83  * buf */
84  char *buf2; /* 2nd string, or abbreviation strxfrm() buf */
85  int buflen1; /* Allocated length of buf1 */
86  int buflen2; /* Allocated length of buf2 */
87  int last_len1; /* Length of last buf1 string/strxfrm() input */
88  int last_len2; /* Length of last buf2 string/strxfrm() blob */
89  int last_returned; /* Last comparison result (cache) */
90  bool cache_blob; /* Does buf2 contain strxfrm() blob, etc? */
91  bool collate_c;
92  Oid typid; /* Actual datatype (text/bpchar/bytea/name) */
93  hyperLogLogState abbr_card; /* Abbreviated key cardinality state */
94  hyperLogLogState full_card; /* Full key cardinality state */
95  double prop_card; /* Required cardinality proportion */
98 
99 /*
100  * Output data for split_text(): we output either to an array or a table.
101  * tupstore and tupdesc must be set up in advance to output to a table.
102  */
103 typedef struct
104 {
109 
110 /*
111  * This should be large enough that most strings will fit, but small enough
112  * that we feel comfortable putting it on the stack
113  */
114 #define TEXTBUFLEN 1024
115 
116 #define DatumGetVarStringP(X) ((VarString *) PG_DETOAST_DATUM(X))
117 #define DatumGetVarStringPP(X) ((VarString *) PG_DETOAST_DATUM_PACKED(X))
118 
119 static int varstrfastcmp_c(Datum x, Datum y, SortSupport ssup);
120 static int bpcharfastcmp_c(Datum x, Datum y, SortSupport ssup);
121 static int namefastcmp_c(Datum x, Datum y, SortSupport ssup);
122 static int varlenafastcmp_locale(Datum x, Datum y, SortSupport ssup);
123 static int namefastcmp_locale(Datum x, Datum y, SortSupport ssup);
124 static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup);
125 static Datum varstr_abbrev_convert(Datum original, SortSupport ssup);
126 static bool varstr_abbrev_abort(int memtupcount, SortSupport ssup);
127 static int32 text_length(Datum str);
128 static text *text_catenate(text *t1, text *t2);
129 static text *text_substring(Datum str,
130  int32 start,
131  int32 length,
132  bool length_not_specified);
133 static text *text_overlay(text *t1, text *t2, int sp, int sl);
134 static int text_position(text *t1, text *t2, Oid collid);
137 static char *text_position_next_internal(char *start_ptr, TextPositionState *state);
141 static void check_collation_set(Oid collid);
142 static int text_cmp(text *arg1, text *arg2, Oid collid);
143 static bytea *bytea_catenate(bytea *t1, bytea *t2);
145  int S,
146  int L,
147  bool length_not_specified);
148 static bytea *bytea_overlay(bytea *t1, bytea *t2, int sp, int sl);
149 static void appendStringInfoText(StringInfo str, const text *t);
150 static bool split_text(FunctionCallInfo fcinfo, SplitTextOutputData *tstate);
151 static void split_text_accum_result(SplitTextOutputData *tstate,
152  text *field_value,
153  text *null_string,
154  Oid collation);
156  const char *fldsep, const char *null_string);
158 static bool text_format_parse_digits(const char **ptr, const char *end_ptr,
159  int *value);
160 static const char *text_format_parse_format(const char *start_ptr,
161  const char *end_ptr,
162  int *argpos, int *widthpos,
163  int *flags, int *width);
164 static void text_format_string_conversion(StringInfo buf, char conversion,
165  FmgrInfo *typOutputInfo,
166  Datum value, bool isNull,
167  int flags, int width);
168 static void text_format_append_string(StringInfo buf, const char *str,
169  int flags, int width);
170 
171 
172 /*****************************************************************************
173  * CONVERSION ROUTINES EXPORTED FOR USE BY C CODE *
174  *****************************************************************************/
175 
176 /*
177  * cstring_to_text
178  *
179  * Create a text value from a null-terminated C string.
180  *
181  * The new text value is freshly palloc'd with a full-size VARHDR.
182  */
183 text *
184 cstring_to_text(const char *s)
185 {
186  return cstring_to_text_with_len(s, strlen(s));
187 }
188 
189 /*
190  * cstring_to_text_with_len
191  *
192  * Same as cstring_to_text except the caller specifies the string length;
193  * the string need not be null_terminated.
194  */
195 text *
196 cstring_to_text_with_len(const char *s, int len)
197 {
198  text *result = (text *) palloc(len + VARHDRSZ);
199 
200  SET_VARSIZE(result, len + VARHDRSZ);
201  memcpy(VARDATA(result), s, len);
202 
203  return result;
204 }
205 
206 /*
207  * text_to_cstring
208  *
209  * Create a palloc'd, null-terminated C string from a text value.
210  *
211  * We support being passed a compressed or toasted text value.
212  * This is a bit bogus since such values shouldn't really be referred to as
213  * "text *", but it seems useful for robustness. If we didn't handle that
214  * case here, we'd need another routine that did, anyway.
215  */
216 char *
218 {
219  /* must cast away the const, unfortunately */
220  text *tunpacked = pg_detoast_datum_packed(unconstify(text *, t));
221  int len = VARSIZE_ANY_EXHDR(tunpacked);
222  char *result;
223 
224  result = (char *) palloc(len + 1);
225  memcpy(result, VARDATA_ANY(tunpacked), len);
226  result[len] = '\0';
227 
228  if (tunpacked != t)
229  pfree(tunpacked);
230 
231  return result;
232 }
233 
234 /*
235  * text_to_cstring_buffer
236  *
237  * Copy a text value into a caller-supplied buffer of size dst_len.
238  *
239  * The text string is truncated if necessary to fit. The result is
240  * guaranteed null-terminated (unless dst_len == 0).
241  *
242  * We support being passed a compressed or toasted text value.
243  * This is a bit bogus since such values shouldn't really be referred to as
244  * "text *", but it seems useful for robustness. If we didn't handle that
245  * case here, we'd need another routine that did, anyway.
246  */
247 void
248 text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
249 {
250  /* must cast away the const, unfortunately */
251  text *srcunpacked = pg_detoast_datum_packed(unconstify(text *, src));
252  size_t src_len = VARSIZE_ANY_EXHDR(srcunpacked);
253 
254  if (dst_len > 0)
255  {
256  dst_len--;
257  if (dst_len >= src_len)
258  dst_len = src_len;
259  else /* ensure truncation is encoding-safe */
260  dst_len = pg_mbcliplen(VARDATA_ANY(srcunpacked), src_len, dst_len);
261  memcpy(dst, VARDATA_ANY(srcunpacked), dst_len);
262  dst[dst_len] = '\0';
263  }
264 
265  if (srcunpacked != src)
266  pfree(srcunpacked);
267 }
268 
269 
270 /*****************************************************************************
271  * USER I/O ROUTINES *
272  *****************************************************************************/
273 
274 
275 #define VAL(CH) ((CH) - '0')
276 #define DIG(VAL) ((VAL) + '0')
277 
278 /*
279  * byteain - converts from printable representation of byte array
280  *
281  * Non-printable characters must be passed as '\nnn' (octal) and are
282  * converted to internal form. '\' must be passed as '\\'.
283  * ereport(ERROR, ...) if bad form.
284  *
285  * BUGS:
286  * The input is scanned twice.
287  * The error checking of input is minimal.
288  */
289 Datum
291 {
292  char *inputText = PG_GETARG_CSTRING(0);
293  Node *escontext = fcinfo->context;
294  char *tp;
295  char *rp;
296  int bc;
297  bytea *result;
298 
299  /* Recognize hex input */
300  if (inputText[0] == '\\' && inputText[1] == 'x')
301  {
302  size_t len = strlen(inputText);
303 
304  bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */
305  result = palloc(bc);
306  bc = hex_decode_safe(inputText + 2, len - 2, VARDATA(result),
307  escontext);
308  SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
309 
310  PG_RETURN_BYTEA_P(result);
311  }
312 
313  /* Else, it's the traditional escaped style */
314  for (bc = 0, tp = inputText; *tp != '\0'; bc++)
315  {
316  if (tp[0] != '\\')
317  tp++;
318  else if ((tp[0] == '\\') &&
319  (tp[1] >= '0' && tp[1] <= '3') &&
320  (tp[2] >= '0' && tp[2] <= '7') &&
321  (tp[3] >= '0' && tp[3] <= '7'))
322  tp += 4;
323  else if ((tp[0] == '\\') &&
324  (tp[1] == '\\'))
325  tp += 2;
326  else
327  {
328  /*
329  * one backslash, not followed by another or ### valid octal
330  */
331  ereturn(escontext, (Datum) 0,
332  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
333  errmsg("invalid input syntax for type %s", "bytea")));
334  }
335  }
336 
337  bc += VARHDRSZ;
338 
339  result = (bytea *) palloc(bc);
340  SET_VARSIZE(result, bc);
341 
342  tp = inputText;
343  rp = VARDATA(result);
344  while (*tp != '\0')
345  {
346  if (tp[0] != '\\')
347  *rp++ = *tp++;
348  else if ((tp[0] == '\\') &&
349  (tp[1] >= '0' && tp[1] <= '3') &&
350  (tp[2] >= '0' && tp[2] <= '7') &&
351  (tp[3] >= '0' && tp[3] <= '7'))
352  {
353  bc = VAL(tp[1]);
354  bc <<= 3;
355  bc += VAL(tp[2]);
356  bc <<= 3;
357  *rp++ = bc + VAL(tp[3]);
358 
359  tp += 4;
360  }
361  else if ((tp[0] == '\\') &&
362  (tp[1] == '\\'))
363  {
364  *rp++ = '\\';
365  tp += 2;
366  }
367  else
368  {
369  /*
370  * We should never get here. The first pass should not allow it.
371  */
372  ereturn(escontext, (Datum) 0,
373  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
374  errmsg("invalid input syntax for type %s", "bytea")));
375  }
376  }
377 
378  PG_RETURN_BYTEA_P(result);
379 }
380 
381 /*
382  * byteaout - converts to printable representation of byte array
383  *
384  * In the traditional escaped format, non-printable characters are
385  * printed as '\nnn' (octal) and '\' as '\\'.
386  */
387 Datum
389 {
390  bytea *vlena = PG_GETARG_BYTEA_PP(0);
391  char *result;
392  char *rp;
393 
395  {
396  /* Print hex format */
397  rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
398  *rp++ = '\\';
399  *rp++ = 'x';
400  rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
401  }
402  else if (bytea_output == BYTEA_OUTPUT_ESCAPE)
403  {
404  /* Print traditional escaped format */
405  char *vp;
406  uint64 len;
407  int i;
408 
409  len = 1; /* empty string has 1 char */
410  vp = VARDATA_ANY(vlena);
411  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
412  {
413  if (*vp == '\\')
414  len += 2;
415  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
416  len += 4;
417  else
418  len++;
419  }
420 
421  /*
422  * In principle len can't overflow uint32 if the input fit in 1GB, but
423  * for safety let's check rather than relying on palloc's internal
424  * check.
425  */
426  if (len > MaxAllocSize)
427  ereport(ERROR,
428  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
429  errmsg_internal("result of bytea output conversion is too large")));
430  rp = result = (char *) palloc(len);
431 
432  vp = VARDATA_ANY(vlena);
433  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
434  {
435  if (*vp == '\\')
436  {
437  *rp++ = '\\';
438  *rp++ = '\\';
439  }
440  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
441  {
442  int val; /* holds unprintable chars */
443 
444  val = *vp;
445  rp[0] = '\\';
446  rp[3] = DIG(val & 07);
447  val >>= 3;
448  rp[2] = DIG(val & 07);
449  val >>= 3;
450  rp[1] = DIG(val & 03);
451  rp += 4;
452  }
453  else
454  *rp++ = *vp;
455  }
456  }
457  else
458  {
459  elog(ERROR, "unrecognized bytea_output setting: %d",
460  bytea_output);
461  rp = result = NULL; /* keep compiler quiet */
462  }
463  *rp = '\0';
464  PG_RETURN_CSTRING(result);
465 }
466 
467 /*
468  * bytearecv - converts external binary format to bytea
469  */
470 Datum
472 {
474  bytea *result;
475  int nbytes;
476 
477  nbytes = buf->len - buf->cursor;
478  result = (bytea *) palloc(nbytes + VARHDRSZ);
479  SET_VARSIZE(result, nbytes + VARHDRSZ);
480  pq_copymsgbytes(buf, VARDATA(result), nbytes);
481  PG_RETURN_BYTEA_P(result);
482 }
483 
484 /*
485  * byteasend - converts bytea to binary format
486  *
487  * This is a special case: just copy the input...
488  */
489 Datum
491 {
492  bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
493 
494  PG_RETURN_BYTEA_P(vlena);
495 }
496 
497 Datum
499 {
501 
502  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
503 
504  /* Append the value unless null, preceding it with the delimiter. */
505  if (!PG_ARGISNULL(1))
506  {
508  bool isfirst = false;
509 
510  /*
511  * You might think we can just throw away the first delimiter, however
512  * we must keep it as we may be a parallel worker doing partial
513  * aggregation building a state to send to the main process. We need
514  * to keep the delimiter of every aggregation so that the combine
515  * function can properly join up the strings of two separately
516  * partially aggregated results. The first delimiter is only stripped
517  * off in the final function. To know how much to strip off the front
518  * of the string, we store the length of the first delimiter in the
519  * StringInfo's cursor field, which we don't otherwise need here.
520  */
521  if (state == NULL)
522  {
523  state = makeStringAggState(fcinfo);
524  isfirst = true;
525  }
526 
527  if (!PG_ARGISNULL(2))
528  {
529  bytea *delim = PG_GETARG_BYTEA_PP(2);
530 
532  VARSIZE_ANY_EXHDR(delim));
533  if (isfirst)
534  state->cursor = VARSIZE_ANY_EXHDR(delim);
535  }
536 
539  }
540 
541  /*
542  * The transition type for string_agg() is declared to be "internal",
543  * which is a pass-by-value type the same size as a pointer.
544  */
545  if (state)
547  PG_RETURN_NULL();
548 }
549 
550 Datum
552 {
554 
555  /* cannot be called directly because of internal-type argument */
556  Assert(AggCheckCallContext(fcinfo, NULL));
557 
558  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
559 
560  if (state != NULL)
561  {
562  /* As per comment in transfn, strip data before the cursor position */
563  bytea *result;
564  int strippedlen = state->len - state->cursor;
565 
566  result = (bytea *) palloc(strippedlen + VARHDRSZ);
567  SET_VARSIZE(result, strippedlen + VARHDRSZ);
568  memcpy(VARDATA(result), &state->data[state->cursor], strippedlen);
569  PG_RETURN_BYTEA_P(result);
570  }
571  else
572  PG_RETURN_NULL();
573 }
574 
575 /*
576  * textin - converts cstring to internal representation
577  */
578 Datum
580 {
581  char *inputText = PG_GETARG_CSTRING(0);
582 
583  PG_RETURN_TEXT_P(cstring_to_text(inputText));
584 }
585 
586 /*
587  * textout - converts internal representation to cstring
588  */
589 Datum
591 {
592  Datum txt = PG_GETARG_DATUM(0);
593 
595 }
596 
597 /*
598  * textrecv - converts external binary format to text
599  */
600 Datum
602 {
604  text *result;
605  char *str;
606  int nbytes;
607 
608  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
609 
610  result = cstring_to_text_with_len(str, nbytes);
611  pfree(str);
612  PG_RETURN_TEXT_P(result);
613 }
614 
615 /*
616  * textsend - converts text to binary format
617  */
618 Datum
620 {
621  text *t = PG_GETARG_TEXT_PP(0);
623 
627 }
628 
629 
630 /*
631  * unknownin - converts cstring to internal representation
632  */
633 Datum
635 {
636  char *str = PG_GETARG_CSTRING(0);
637 
638  /* representation is same as cstring */
640 }
641 
642 /*
643  * unknownout - converts internal representation to cstring
644  */
645 Datum
647 {
648  /* representation is same as cstring */
649  char *str = PG_GETARG_CSTRING(0);
650 
652 }
653 
654 /*
655  * unknownrecv - converts external binary format to unknown
656  */
657 Datum
659 {
661  char *str;
662  int nbytes;
663 
664  str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
665  /* representation is same as cstring */
667 }
668 
669 /*
670  * unknownsend - converts unknown to binary format
671  */
672 Datum
674 {
675  /* representation is same as cstring */
676  char *str = PG_GETARG_CSTRING(0);
678 
680  pq_sendtext(&buf, str, strlen(str));
682 }
683 
684 
685 /* ========== PUBLIC ROUTINES ========== */
686 
687 /*
688  * textlen -
689  * returns the logical length of a text*
690  * (which is less than the VARSIZE of the text*)
691  */
692 Datum
694 {
696 
697  /* try to avoid decompressing argument */
699 }
700 
701 /*
702  * text_length -
703  * Does the real work for textlen()
704  *
705  * This is broken out so it can be called directly by other string processing
706  * functions. Note that the argument is passed as a Datum, to indicate that
707  * it may still be in compressed form. We can avoid decompressing it at all
708  * in some cases.
709  */
710 static int32
712 {
713  /* fastpath when max encoding length is one */
716  else
717  {
718  text *t = DatumGetTextPP(str);
719 
721  VARSIZE_ANY_EXHDR(t)));
722  }
723 }
724 
725 /*
726  * textoctetlen -
727  * returns the physical length of a text*
728  * (which is less than the VARSIZE of the text*)
729  */
730 Datum
732 {
734 
735  /* We need not detoast the input at all */
737 }
738 
739 /*
740  * textcat -
741  * takes two text* and returns a text* that is the concatenation of
742  * the two.
743  *
744  * Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
745  * Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10.
746  * Allocate space for output in all cases.
747  * XXX - thomas 1997-07-10
748  */
749 Datum
751 {
752  text *t1 = PG_GETARG_TEXT_PP(0);
753  text *t2 = PG_GETARG_TEXT_PP(1);
754 
756 }
757 
758 /*
759  * text_catenate
760  * Guts of textcat(), broken out so it can be used by other functions
761  *
762  * Arguments can be in short-header form, but not compressed or out-of-line
763  */
764 static text *
766 {
767  text *result;
768  int len1,
769  len2,
770  len;
771  char *ptr;
772 
773  len1 = VARSIZE_ANY_EXHDR(t1);
774  len2 = VARSIZE_ANY_EXHDR(t2);
775 
776  /* paranoia ... probably should throw error instead? */
777  if (len1 < 0)
778  len1 = 0;
779  if (len2 < 0)
780  len2 = 0;
781 
782  len = len1 + len2 + VARHDRSZ;
783  result = (text *) palloc(len);
784 
785  /* Set size of result string... */
786  SET_VARSIZE(result, len);
787 
788  /* Fill data field of result string... */
789  ptr = VARDATA(result);
790  if (len1 > 0)
791  memcpy(ptr, VARDATA_ANY(t1), len1);
792  if (len2 > 0)
793  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
794 
795  return result;
796 }
797 
798 /*
799  * charlen_to_bytelen()
800  * Compute the number of bytes occupied by n characters starting at *p
801  *
802  * It is caller's responsibility that there actually are n characters;
803  * the string need not be null-terminated.
804  */
805 static int
806 charlen_to_bytelen(const char *p, int n)
807 {
809  {
810  /* Optimization for single-byte encodings */
811  return n;
812  }
813  else
814  {
815  const char *s;
816 
817  for (s = p; n > 0; n--)
818  s += pg_mblen(s);
819 
820  return s - p;
821  }
822 }
823 
824 /*
825  * text_substr()
826  * Return a substring starting at the specified position.
827  * - thomas 1997-12-31
828  *
829  * Input:
830  * - string
831  * - starting position (is one-based)
832  * - string length
833  *
834  * If the starting position is zero or less, then return from the start of the string
835  * adjusting the length to be consistent with the "negative start" per SQL.
836  * If the length is less than zero, return the remaining string.
837  *
838  * Added multibyte support.
839  * - Tatsuo Ishii 1998-4-21
840  * Changed behavior if starting position is less than one to conform to SQL behavior.
841  * Formerly returned the entire string; now returns a portion.
842  * - Thomas Lockhart 1998-12-10
843  * Now uses faster TOAST-slicing interface
844  * - John Gray 2002-02-22
845  * Remove "#ifdef MULTIBYTE" and test for encoding_max_length instead. Change
846  * behaviors conflicting with SQL to meet SQL (if E = S + L < S throw
847  * error; if E < 1, return '', not entire string). Fixed MB related bug when
848  * S > LC and < LC + 4 sometimes garbage characters are returned.
849  * - Joe Conway 2002-08-10
850  */
851 Datum
853 {
855  PG_GETARG_INT32(1),
856  PG_GETARG_INT32(2),
857  false));
858 }
859 
860 /*
861  * text_substr_no_len -
862  * Wrapper to avoid opr_sanity failure due to
863  * one function accepting a different number of args.
864  */
865 Datum
867 {
869  PG_GETARG_INT32(1),
870  -1, true));
871 }
872 
873 /*
874  * text_substring -
875  * Does the real work for text_substr() and text_substr_no_len()
876  *
877  * This is broken out so it can be called directly by other string processing
878  * functions. Note that the argument is passed as a Datum, to indicate that
879  * it may still be in compressed/toasted form. We can avoid detoasting all
880  * of it in some cases.
881  *
882  * The result is always a freshly palloc'd datum.
883  */
884 static text *
885 text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
886 {
888  int32 S = start; /* start position */
889  int32 S1; /* adjusted start position */
890  int32 L1; /* adjusted substring length */
891  int32 E; /* end position */
892 
893  /*
894  * SQL99 says S can be zero or negative, but we still must fetch from the
895  * start of the string.
896  */
897  S1 = Max(S, 1);
898 
899  /* life is easy if the encoding max length is 1 */
900  if (eml == 1)
901  {
902  if (length_not_specified) /* special case - get length to end of
903  * string */
904  L1 = -1;
905  else if (length < 0)
906  {
907  /* SQL99 says to throw an error for E < S, i.e., negative length */
908  ereport(ERROR,
909  (errcode(ERRCODE_SUBSTRING_ERROR),
910  errmsg("negative substring length not allowed")));
911  L1 = -1; /* silence stupider compilers */
912  }
913  else if (pg_add_s32_overflow(S, length, &E))
914  {
915  /*
916  * L could be large enough for S + L to overflow, in which case
917  * the substring must run to end of string.
918  */
919  L1 = -1;
920  }
921  else
922  {
923  /*
924  * A zero or negative value for the end position can happen if the
925  * start was negative or one. SQL99 says to return a zero-length
926  * string.
927  */
928  if (E < 1)
929  return cstring_to_text("");
930 
931  L1 = E - S1;
932  }
933 
934  /*
935  * If the start position is past the end of the string, SQL99 says to
936  * return a zero-length string -- DatumGetTextPSlice() will do that
937  * for us. We need only convert S1 to zero-based starting position.
938  */
939  return DatumGetTextPSlice(str, S1 - 1, L1);
940  }
941  else if (eml > 1)
942  {
943  /*
944  * When encoding max length is > 1, we can't get LC without
945  * detoasting, so we'll grab a conservatively large slice now and go
946  * back later to do the right thing
947  */
948  int32 slice_start;
949  int32 slice_size;
950  int32 slice_strlen;
951  text *slice;
952  int32 E1;
953  int32 i;
954  char *p;
955  char *s;
956  text *ret;
957 
958  /*
959  * We need to start at position zero because there is no way to know
960  * in advance which byte offset corresponds to the supplied start
961  * position.
962  */
963  slice_start = 0;
964 
965  if (length_not_specified) /* special case - get length to end of
966  * string */
967  slice_size = L1 = -1;
968  else if (length < 0)
969  {
970  /* SQL99 says to throw an error for E < S, i.e., negative length */
971  ereport(ERROR,
972  (errcode(ERRCODE_SUBSTRING_ERROR),
973  errmsg("negative substring length not allowed")));
974  slice_size = L1 = -1; /* silence stupider compilers */
975  }
976  else if (pg_add_s32_overflow(S, length, &E))
977  {
978  /*
979  * L could be large enough for S + L to overflow, in which case
980  * the substring must run to end of string.
981  */
982  slice_size = L1 = -1;
983  }
984  else
985  {
986  /*
987  * A zero or negative value for the end position can happen if the
988  * start was negative or one. SQL99 says to return a zero-length
989  * string.
990  */
991  if (E < 1)
992  return cstring_to_text("");
993 
994  /*
995  * if E is past the end of the string, the tuple toaster will
996  * truncate the length for us
997  */
998  L1 = E - S1;
999 
1000  /*
1001  * Total slice size in bytes can't be any longer than the start
1002  * position plus substring length times the encoding max length.
1003  * If that overflows, we can just use -1.
1004  */
1005  if (pg_mul_s32_overflow(E, eml, &slice_size))
1006  slice_size = -1;
1007  }
1008 
1009  /*
1010  * If we're working with an untoasted source, no need to do an extra
1011  * copying step.
1012  */
1015  slice = DatumGetTextPSlice(str, slice_start, slice_size);
1016  else
1017  slice = (text *) DatumGetPointer(str);
1018 
1019  /* see if we got back an empty string */
1020  if (VARSIZE_ANY_EXHDR(slice) == 0)
1021  {
1022  if (slice != (text *) DatumGetPointer(str))
1023  pfree(slice);
1024  return cstring_to_text("");
1025  }
1026 
1027  /* Now we can get the actual length of the slice in MB characters */
1028  slice_strlen = pg_mbstrlen_with_len(VARDATA_ANY(slice),
1029  VARSIZE_ANY_EXHDR(slice));
1030 
1031  /*
1032  * Check that the start position wasn't > slice_strlen. If so, SQL99
1033  * says to return a zero-length string.
1034  */
1035  if (S1 > slice_strlen)
1036  {
1037  if (slice != (text *) DatumGetPointer(str))
1038  pfree(slice);
1039  return cstring_to_text("");
1040  }
1041 
1042  /*
1043  * Adjust L1 and E1 now that we know the slice string length. Again
1044  * remember that S1 is one based, and slice_start is zero based.
1045  */
1046  if (L1 > -1)
1047  E1 = Min(S1 + L1, slice_start + 1 + slice_strlen);
1048  else
1049  E1 = slice_start + 1 + slice_strlen;
1050 
1051  /*
1052  * Find the start position in the slice; remember S1 is not zero based
1053  */
1054  p = VARDATA_ANY(slice);
1055  for (i = 0; i < S1 - 1; i++)
1056  p += pg_mblen(p);
1057 
1058  /* hang onto a pointer to our start position */
1059  s = p;
1060 
1061  /*
1062  * Count the actual bytes used by the substring of the requested
1063  * length.
1064  */
1065  for (i = S1; i < E1; i++)
1066  p += pg_mblen(p);
1067 
1068  ret = (text *) palloc(VARHDRSZ + (p - s));
1069  SET_VARSIZE(ret, VARHDRSZ + (p - s));
1070  memcpy(VARDATA(ret), s, (p - s));
1071 
1072  if (slice != (text *) DatumGetPointer(str))
1073  pfree(slice);
1074 
1075  return ret;
1076  }
1077  else
1078  elog(ERROR, "invalid backend encoding: encoding max length < 1");
1079 
1080  /* not reached: suppress compiler warning */
1081  return NULL;
1082 }
1083 
1084 /*
1085  * textoverlay
1086  * Replace specified substring of first string with second
1087  *
1088  * The SQL standard defines OVERLAY() in terms of substring and concatenation.
1089  * This code is a direct implementation of what the standard says.
1090  */
1091 Datum
1093 {
1094  text *t1 = PG_GETARG_TEXT_PP(0);
1095  text *t2 = PG_GETARG_TEXT_PP(1);
1096  int sp = PG_GETARG_INT32(2); /* substring start position */
1097  int sl = PG_GETARG_INT32(3); /* substring length */
1098 
1099  PG_RETURN_TEXT_P(text_overlay(t1, t2, sp, sl));
1100 }
1101 
1102 Datum
1104 {
1105  text *t1 = PG_GETARG_TEXT_PP(0);
1106  text *t2 = PG_GETARG_TEXT_PP(1);
1107  int sp = PG_GETARG_INT32(2); /* substring start position */
1108  int sl;
1109 
1110  sl = text_length(PointerGetDatum(t2)); /* defaults to length(t2) */
1111  PG_RETURN_TEXT_P(text_overlay(t1, t2, sp, sl));
1112 }
1113 
1114 static text *
1115 text_overlay(text *t1, text *t2, int sp, int sl)
1116 {
1117  text *result;
1118  text *s1;
1119  text *s2;
1120  int sp_pl_sl;
1121 
1122  /*
1123  * Check for possible integer-overflow cases. For negative sp, throw a
1124  * "substring length" error because that's what should be expected
1125  * according to the spec's definition of OVERLAY().
1126  */
1127  if (sp <= 0)
1128  ereport(ERROR,
1129  (errcode(ERRCODE_SUBSTRING_ERROR),
1130  errmsg("negative substring length not allowed")));
1131  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
1132  ereport(ERROR,
1133  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1134  errmsg("integer out of range")));
1135 
1136  s1 = text_substring(PointerGetDatum(t1), 1, sp - 1, false);
1137  s2 = text_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
1138  result = text_catenate(s1, t2);
1139  result = text_catenate(result, s2);
1140 
1141  return result;
1142 }
1143 
1144 /*
1145  * textpos -
1146  * Return the position of the specified substring.
1147  * Implements the SQL POSITION() function.
1148  * Ref: A Guide To The SQL Standard, Date & Darwen, 1997
1149  * - thomas 1997-07-27
1150  */
1151 Datum
1153 {
1154  text *str = PG_GETARG_TEXT_PP(0);
1155  text *search_str = PG_GETARG_TEXT_PP(1);
1156 
1158 }
1159 
1160 /*
1161  * text_position -
1162  * Does the real work for textpos()
1163  *
1164  * Inputs:
1165  * t1 - string to be searched
1166  * t2 - pattern to match within t1
1167  * Result:
1168  * Character index of the first matched char, starting from 1,
1169  * or 0 if no match.
1170  *
1171  * This is broken out so it can be called directly by other string processing
1172  * functions.
1173  */
1174 static int
1176 {
1178  int result;
1179 
1180  /* Empty needle always matches at position 1 */
1181  if (VARSIZE_ANY_EXHDR(t2) < 1)
1182  return 1;
1183 
1184  /* Otherwise, can't match if haystack is shorter than needle */
1185  if (VARSIZE_ANY_EXHDR(t1) < VARSIZE_ANY_EXHDR(t2))
1186  return 0;
1187 
1188  text_position_setup(t1, t2, collid, &state);
1189  if (!text_position_next(&state))
1190  result = 0;
1191  else
1194  return result;
1195 }
1196 
1197 
1198 /*
1199  * text_position_setup, text_position_next, text_position_cleanup -
1200  * Component steps of text_position()
1201  *
1202  * These are broken out so that a string can be efficiently searched for
1203  * multiple occurrences of the same pattern. text_position_next may be
1204  * called multiple times, and it advances to the next match on each call.
1205  * text_position_get_match_ptr() and text_position_get_match_pos() return
1206  * a pointer or 1-based character position of the last match, respectively.
1207  *
1208  * The "state" variable is normally just a local variable in the caller.
1209  *
1210  * NOTE: text_position_next skips over the matched portion. For example,
1211  * searching for "xx" in "xxx" returns only one match, not two.
1212  */
1213 
1214 static void
1216 {
1217  int len1 = VARSIZE_ANY_EXHDR(t1);
1218  int len2 = VARSIZE_ANY_EXHDR(t2);
1219  pg_locale_t mylocale = 0;
1220 
1222 
1223  if (!lc_collate_is_c(collid))
1224  mylocale = pg_newlocale_from_collation(collid);
1225 
1226  if (!pg_locale_deterministic(mylocale))
1227  ereport(ERROR,
1228  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1229  errmsg("nondeterministic collations are not supported for substring searches")));
1230 
1231  Assert(len1 > 0);
1232  Assert(len2 > 0);
1233 
1234  /*
1235  * Even with a multi-byte encoding, we perform the search using the raw
1236  * byte sequence, ignoring multibyte issues. For UTF-8, that works fine,
1237  * because in UTF-8 the byte sequence of one character cannot contain
1238  * another character. For other multi-byte encodings, we do the search
1239  * initially as a simple byte search, ignoring multibyte issues, but
1240  * verify afterwards that the match we found is at a character boundary,
1241  * and continue the search if it was a false match.
1242  */
1244  state->is_multibyte_char_in_char = false;
1245  else if (GetDatabaseEncoding() == PG_UTF8)
1246  state->is_multibyte_char_in_char = false;
1247  else
1248  state->is_multibyte_char_in_char = true;
1249 
1250  state->str1 = VARDATA_ANY(t1);
1251  state->str2 = VARDATA_ANY(t2);
1252  state->len1 = len1;
1253  state->len2 = len2;
1254  state->last_match = NULL;
1255  state->refpoint = state->str1;
1256  state->refpos = 0;
1257 
1258  /*
1259  * Prepare the skip table for Boyer-Moore-Horspool searching. In these
1260  * notes we use the terminology that the "haystack" is the string to be
1261  * searched (t1) and the "needle" is the pattern being sought (t2).
1262  *
1263  * If the needle is empty or bigger than the haystack then there is no
1264  * point in wasting cycles initializing the table. We also choose not to
1265  * use B-M-H for needles of length 1, since the skip table can't possibly
1266  * save anything in that case.
1267  */
1268  if (len1 >= len2 && len2 > 1)
1269  {
1270  int searchlength = len1 - len2;
1271  int skiptablemask;
1272  int last;
1273  int i;
1274  const char *str2 = state->str2;
1275 
1276  /*
1277  * First we must determine how much of the skip table to use. The
1278  * declaration of TextPositionState allows up to 256 elements, but for
1279  * short search problems we don't really want to have to initialize so
1280  * many elements --- it would take too long in comparison to the
1281  * actual search time. So we choose a useful skip table size based on
1282  * the haystack length minus the needle length. The closer the needle
1283  * length is to the haystack length the less useful skipping becomes.
1284  *
1285  * Note: since we use bit-masking to select table elements, the skip
1286  * table size MUST be a power of 2, and so the mask must be 2^N-1.
1287  */
1288  if (searchlength < 16)
1289  skiptablemask = 3;
1290  else if (searchlength < 64)
1291  skiptablemask = 7;
1292  else if (searchlength < 128)
1293  skiptablemask = 15;
1294  else if (searchlength < 512)
1295  skiptablemask = 31;
1296  else if (searchlength < 2048)
1297  skiptablemask = 63;
1298  else if (searchlength < 4096)
1299  skiptablemask = 127;
1300  else
1301  skiptablemask = 255;
1302  state->skiptablemask = skiptablemask;
1303 
1304  /*
1305  * Initialize the skip table. We set all elements to the needle
1306  * length, since this is the correct skip distance for any character
1307  * not found in the needle.
1308  */
1309  for (i = 0; i <= skiptablemask; i++)
1310  state->skiptable[i] = len2;
1311 
1312  /*
1313  * Now examine the needle. For each character except the last one,
1314  * set the corresponding table element to the appropriate skip
1315  * distance. Note that when two characters share the same skip table
1316  * entry, the one later in the needle must determine the skip
1317  * distance.
1318  */
1319  last = len2 - 1;
1320 
1321  for (i = 0; i < last; i++)
1322  state->skiptable[(unsigned char) str2[i] & skiptablemask] = last - i;
1323  }
1324 }
1325 
1326 /*
1327  * Advance to the next match, starting from the end of the previous match
1328  * (or the beginning of the string, on first call). Returns true if a match
1329  * is found.
1330  *
1331  * Note that this refuses to match an empty-string needle. Most callers
1332  * will have handled that case specially and we'll never see it here.
1333  */
1334 static bool
1336 {
1337  int needle_len = state->len2;
1338  char *start_ptr;
1339  char *matchptr;
1340 
1341  if (needle_len <= 0)
1342  return false; /* result for empty pattern */
1343 
1344  /* Start from the point right after the previous match. */
1345  if (state->last_match)
1346  start_ptr = state->last_match + needle_len;
1347  else
1348  start_ptr = state->str1;
1349 
1350 retry:
1351  matchptr = text_position_next_internal(start_ptr, state);
1352 
1353  if (!matchptr)
1354  return false;
1355 
1356  /*
1357  * Found a match for the byte sequence. If this is a multibyte encoding,
1358  * where one character's byte sequence can appear inside a longer
1359  * multi-byte character, we need to verify that the match was at a
1360  * character boundary, not in the middle of a multi-byte character.
1361  */
1362  if (state->is_multibyte_char_in_char)
1363  {
1364  /* Walk one character at a time, until we reach the match. */
1365 
1366  /* the search should never move backwards. */
1367  Assert(state->refpoint <= matchptr);
1368 
1369  while (state->refpoint < matchptr)
1370  {
1371  /* step to next character. */
1372  state->refpoint += pg_mblen(state->refpoint);
1373  state->refpos++;
1374 
1375  /*
1376  * If we stepped over the match's start position, then it was a
1377  * false positive, where the byte sequence appeared in the middle
1378  * of a multi-byte character. Skip it, and continue the search at
1379  * the next character boundary.
1380  */
1381  if (state->refpoint > matchptr)
1382  {
1383  start_ptr = state->refpoint;
1384  goto retry;
1385  }
1386  }
1387  }
1388 
1389  state->last_match = matchptr;
1390  return true;
1391 }
1392 
1393 /*
1394  * Subroutine of text_position_next(). This searches for the raw byte
1395  * sequence, ignoring any multi-byte encoding issues. Returns the first
1396  * match starting at 'start_ptr', or NULL if no match is found.
1397  */
1398 static char *
1400 {
1401  int haystack_len = state->len1;
1402  int needle_len = state->len2;
1403  int skiptablemask = state->skiptablemask;
1404  const char *haystack = state->str1;
1405  const char *needle = state->str2;
1406  const char *haystack_end = &haystack[haystack_len];
1407  const char *hptr;
1408 
1409  Assert(start_ptr >= haystack && start_ptr <= haystack_end);
1410 
1411  if (needle_len == 1)
1412  {
1413  /* No point in using B-M-H for a one-character needle */
1414  char nchar = *needle;
1415 
1416  hptr = start_ptr;
1417  while (hptr < haystack_end)
1418  {
1419  if (*hptr == nchar)
1420  return (char *) hptr;
1421  hptr++;
1422  }
1423  }
1424  else
1425  {
1426  const char *needle_last = &needle[needle_len - 1];
1427 
1428  /* Start at startpos plus the length of the needle */
1429  hptr = start_ptr + needle_len - 1;
1430  while (hptr < haystack_end)
1431  {
1432  /* Match the needle scanning *backward* */
1433  const char *nptr;
1434  const char *p;
1435 
1436  nptr = needle_last;
1437  p = hptr;
1438  while (*nptr == *p)
1439  {
1440  /* Matched it all? If so, return 1-based position */
1441  if (nptr == needle)
1442  return (char *) p;
1443  nptr--, p--;
1444  }
1445 
1446  /*
1447  * No match, so use the haystack char at hptr to decide how far to
1448  * advance. If the needle had any occurrence of that character
1449  * (or more precisely, one sharing the same skiptable entry)
1450  * before its last character, then we advance far enough to align
1451  * the last such needle character with that haystack position.
1452  * Otherwise we can advance by the whole needle length.
1453  */
1454  hptr += state->skiptable[(unsigned char) *hptr & skiptablemask];
1455  }
1456  }
1457 
1458  return 0; /* not found */
1459 }
1460 
1461 /*
1462  * Return a pointer to the current match.
1463  *
1464  * The returned pointer points into the original haystack string.
1465  */
1466 static char *
1468 {
1469  return state->last_match;
1470 }
1471 
1472 /*
1473  * Return the offset of the current match.
1474  *
1475  * The offset is in characters, 1-based.
1476  */
1477 static int
1479 {
1480  /* Convert the byte position to char position. */
1481  state->refpos += pg_mbstrlen_with_len(state->refpoint,
1482  state->last_match - state->refpoint);
1483  state->refpoint = state->last_match;
1484  return state->refpos + 1;
1485 }
1486 
1487 /*
1488  * Reset search state to the initial state installed by text_position_setup.
1489  *
1490  * The next call to text_position_next will search from the beginning
1491  * of the string.
1492  */
1493 static void
1495 {
1496  state->last_match = NULL;
1497  state->refpoint = state->str1;
1498  state->refpos = 0;
1499 }
1500 
1501 static void
1503 {
1504  /* no cleanup needed */
1505 }
1506 
1507 
1508 static void
1510 {
1511  if (!OidIsValid(collid))
1512  {
1513  /*
1514  * This typically means that the parser could not resolve a conflict
1515  * of implicit collations, so report it that way.
1516  */
1517  ereport(ERROR,
1518  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1519  errmsg("could not determine which collation to use for string comparison"),
1520  errhint("Use the COLLATE clause to set the collation explicitly.")));
1521  }
1522 }
1523 
1524 /* varstr_cmp()
1525  * Comparison function for text strings with given lengths.
1526  * Includes locale support, but must copy strings to temporary memory
1527  * to allow null-termination for inputs to strcoll().
1528  * Returns an integer less than, equal to, or greater than zero, indicating
1529  * whether arg1 is less than, equal to, or greater than arg2.
1530  *
1531  * Note: many functions that depend on this are marked leakproof; therefore,
1532  * avoid reporting the actual contents of the input when throwing errors.
1533  * All errors herein should be things that can't happen except on corrupt
1534  * data, anyway; otherwise we will have trouble with indexing strings that
1535  * would cause them.
1536  */
1537 int
1538 varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
1539 {
1540  int result;
1541 
1543 
1544  /*
1545  * Unfortunately, there is no strncoll(), so in the non-C locale case we
1546  * have to do some memory copying. This turns out to be significantly
1547  * slower, so we optimize the case where LC_COLLATE is C. We also try to
1548  * optimize relatively-short strings by avoiding palloc/pfree overhead.
1549  */
1550  if (lc_collate_is_c(collid))
1551  {
1552  result = memcmp(arg1, arg2, Min(len1, len2));
1553  if ((result == 0) && (len1 != len2))
1554  result = (len1 < len2) ? -1 : 1;
1555  }
1556  else
1557  {
1558  pg_locale_t mylocale;
1559 
1560  mylocale = pg_newlocale_from_collation(collid);
1561 
1562  /*
1563  * memcmp() can't tell us which of two unequal strings sorts first,
1564  * but it's a cheap way to tell if they're equal. Testing shows that
1565  * memcmp() followed by strcoll() is only trivially slower than
1566  * strcoll() by itself, so we don't lose much if this doesn't work out
1567  * very often, and if it does - for example, because there are many
1568  * equal strings in the input - then we win big by avoiding expensive
1569  * collation-aware comparisons.
1570  */
1571  if (len1 == len2 && memcmp(arg1, arg2, len1) == 0)
1572  return 0;
1573 
1574  result = pg_strncoll(arg1, len1, arg2, len2, mylocale);
1575 
1576  /* Break tie if necessary. */
1577  if (result == 0 && pg_locale_deterministic(mylocale))
1578  {
1579  result = memcmp(arg1, arg2, Min(len1, len2));
1580  if ((result == 0) && (len1 != len2))
1581  result = (len1 < len2) ? -1 : 1;
1582  }
1583  }
1584 
1585  return result;
1586 }
1587 
1588 /* text_cmp()
1589  * Internal comparison function for text strings.
1590  * Returns -1, 0 or 1
1591  */
1592 static int
1593 text_cmp(text *arg1, text *arg2, Oid collid)
1594 {
1595  char *a1p,
1596  *a2p;
1597  int len1,
1598  len2;
1599 
1600  a1p = VARDATA_ANY(arg1);
1601  a2p = VARDATA_ANY(arg2);
1602 
1603  len1 = VARSIZE_ANY_EXHDR(arg1);
1604  len2 = VARSIZE_ANY_EXHDR(arg2);
1605 
1606  return varstr_cmp(a1p, len1, a2p, len2, collid);
1607 }
1608 
1609 /*
1610  * Comparison functions for text strings.
1611  *
1612  * Note: btree indexes need these routines not to leak memory; therefore,
1613  * be careful to free working copies of toasted datums. Most places don't
1614  * need to be so careful.
1615  */
1616 
1617 Datum
1619 {
1621  bool locale_is_c = false;
1622  pg_locale_t mylocale = 0;
1623  bool result;
1624 
1626 
1627  if (lc_collate_is_c(collid))
1628  locale_is_c = true;
1629  else
1630  mylocale = pg_newlocale_from_collation(collid);
1631 
1632  if (locale_is_c || pg_locale_deterministic(mylocale))
1633  {
1634  Datum arg1 = PG_GETARG_DATUM(0);
1635  Datum arg2 = PG_GETARG_DATUM(1);
1636  Size len1,
1637  len2;
1638 
1639  /*
1640  * Since we only care about equality or not-equality, we can avoid all
1641  * the expense of strcoll() here, and just do bitwise comparison. In
1642  * fact, we don't even have to do a bitwise comparison if we can show
1643  * the lengths of the strings are unequal; which might save us from
1644  * having to detoast one or both values.
1645  */
1646  len1 = toast_raw_datum_size(arg1);
1647  len2 = toast_raw_datum_size(arg2);
1648  if (len1 != len2)
1649  result = false;
1650  else
1651  {
1652  text *targ1 = DatumGetTextPP(arg1);
1653  text *targ2 = DatumGetTextPP(arg2);
1654 
1655  result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2),
1656  len1 - VARHDRSZ) == 0);
1657 
1658  PG_FREE_IF_COPY(targ1, 0);
1659  PG_FREE_IF_COPY(targ2, 1);
1660  }
1661  }
1662  else
1663  {
1664  text *arg1 = PG_GETARG_TEXT_PP(0);
1665  text *arg2 = PG_GETARG_TEXT_PP(1);
1666 
1667  result = (text_cmp(arg1, arg2, collid) == 0);
1668 
1669  PG_FREE_IF_COPY(arg1, 0);
1670  PG_FREE_IF_COPY(arg2, 1);
1671  }
1672 
1673  PG_RETURN_BOOL(result);
1674 }
1675 
1676 Datum
1678 {
1680  bool locale_is_c = false;
1681  pg_locale_t mylocale = 0;
1682  bool result;
1683 
1685 
1686  if (lc_collate_is_c(collid))
1687  locale_is_c = true;
1688  else
1689  mylocale = pg_newlocale_from_collation(collid);
1690 
1691  if (locale_is_c || pg_locale_deterministic(mylocale))
1692  {
1693  Datum arg1 = PG_GETARG_DATUM(0);
1694  Datum arg2 = PG_GETARG_DATUM(1);
1695  Size len1,
1696  len2;
1697 
1698  /* See comment in texteq() */
1699  len1 = toast_raw_datum_size(arg1);
1700  len2 = toast_raw_datum_size(arg2);
1701  if (len1 != len2)
1702  result = true;
1703  else
1704  {
1705  text *targ1 = DatumGetTextPP(arg1);
1706  text *targ2 = DatumGetTextPP(arg2);
1707 
1708  result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2),
1709  len1 - VARHDRSZ) != 0);
1710 
1711  PG_FREE_IF_COPY(targ1, 0);
1712  PG_FREE_IF_COPY(targ2, 1);
1713  }
1714  }
1715  else
1716  {
1717  text *arg1 = PG_GETARG_TEXT_PP(0);
1718  text *arg2 = PG_GETARG_TEXT_PP(1);
1719 
1720  result = (text_cmp(arg1, arg2, collid) != 0);
1721 
1722  PG_FREE_IF_COPY(arg1, 0);
1723  PG_FREE_IF_COPY(arg2, 1);
1724  }
1725 
1726  PG_RETURN_BOOL(result);
1727 }
1728 
1729 Datum
1731 {
1732  text *arg1 = PG_GETARG_TEXT_PP(0);
1733  text *arg2 = PG_GETARG_TEXT_PP(1);
1734  bool result;
1735 
1736  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
1737 
1738  PG_FREE_IF_COPY(arg1, 0);
1739  PG_FREE_IF_COPY(arg2, 1);
1740 
1741  PG_RETURN_BOOL(result);
1742 }
1743 
1744 Datum
1746 {
1747  text *arg1 = PG_GETARG_TEXT_PP(0);
1748  text *arg2 = PG_GETARG_TEXT_PP(1);
1749  bool result;
1750 
1751  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1752 
1753  PG_FREE_IF_COPY(arg1, 0);
1754  PG_FREE_IF_COPY(arg2, 1);
1755 
1756  PG_RETURN_BOOL(result);
1757 }
1758 
1759 Datum
1761 {
1762  text *arg1 = PG_GETARG_TEXT_PP(0);
1763  text *arg2 = PG_GETARG_TEXT_PP(1);
1764  bool result;
1765 
1766  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1767 
1768  PG_FREE_IF_COPY(arg1, 0);
1769  PG_FREE_IF_COPY(arg2, 1);
1770 
1771  PG_RETURN_BOOL(result);
1772 }
1773 
1774 Datum
1776 {
1777  text *arg1 = PG_GETARG_TEXT_PP(0);
1778  text *arg2 = PG_GETARG_TEXT_PP(1);
1779  bool result;
1780 
1781  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1782 
1783  PG_FREE_IF_COPY(arg1, 0);
1784  PG_FREE_IF_COPY(arg2, 1);
1785 
1786  PG_RETURN_BOOL(result);
1787 }
1788 
1789 Datum
1791 {
1792  Datum arg1 = PG_GETARG_DATUM(0);
1793  Datum arg2 = PG_GETARG_DATUM(1);
1795  pg_locale_t mylocale = 0;
1796  bool result;
1797  Size len1,
1798  len2;
1799 
1801 
1802  if (!lc_collate_is_c(collid))
1803  mylocale = pg_newlocale_from_collation(collid);
1804 
1805  if (!pg_locale_deterministic(mylocale))
1806  ereport(ERROR,
1807  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1808  errmsg("nondeterministic collations are not supported for substring searches")));
1809 
1810  len1 = toast_raw_datum_size(arg1);
1811  len2 = toast_raw_datum_size(arg2);
1812  if (len2 > len1)
1813  result = false;
1814  else
1815  {
1816  text *targ1 = text_substring(arg1, 1, len2, false);
1817  text *targ2 = DatumGetTextPP(arg2);
1818 
1819  result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2),
1820  VARSIZE_ANY_EXHDR(targ2)) == 0);
1821 
1822  PG_FREE_IF_COPY(targ1, 0);
1823  PG_FREE_IF_COPY(targ2, 1);
1824  }
1825 
1826  PG_RETURN_BOOL(result);
1827 }
1828 
1829 Datum
1831 {
1832  text *arg1 = PG_GETARG_TEXT_PP(0);
1833  text *arg2 = PG_GETARG_TEXT_PP(1);
1834  int32 result;
1835 
1836  result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1837 
1838  PG_FREE_IF_COPY(arg1, 0);
1839  PG_FREE_IF_COPY(arg2, 1);
1840 
1841  PG_RETURN_INT32(result);
1842 }
1843 
1844 Datum
1846 {
1848  Oid collid = ssup->ssup_collation;
1849  MemoryContext oldcontext;
1850 
1851  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1852 
1853  /* Use generic string SortSupport */
1854  varstr_sortsupport(ssup, TEXTOID, collid);
1855 
1856  MemoryContextSwitchTo(oldcontext);
1857 
1858  PG_RETURN_VOID();
1859 }
1860 
1861 /*
1862  * Generic sortsupport interface for character type's operator classes.
1863  * Includes locale support, and support for BpChar semantics (i.e. removing
1864  * trailing spaces before comparison).
1865  *
1866  * Relies on the assumption that text, VarChar, BpChar, and bytea all have the
1867  * same representation. Callers that always use the C collation (e.g.
1868  * non-collatable type callers like bytea) may have NUL bytes in their strings;
1869  * this will not work with any other collation, though.
1870  */
1871 void
1873 {
1874  bool abbreviate = ssup->abbreviate;
1875  bool collate_c = false;
1876  VarStringSortSupport *sss;
1877  pg_locale_t locale = 0;
1878 
1880 
1881  /*
1882  * If possible, set ssup->comparator to a function which can be used to
1883  * directly compare two datums. If we can do this, we'll avoid the
1884  * overhead of a trip through the fmgr layer for every comparison, which
1885  * can be substantial.
1886  *
1887  * Most typically, we'll set the comparator to varlenafastcmp_locale,
1888  * which uses strcoll() to perform comparisons. We use that for the
1889  * BpChar case too, but type NAME uses namefastcmp_locale. However, if
1890  * LC_COLLATE = C, we can make things quite a bit faster with
1891  * varstrfastcmp_c, bpcharfastcmp_c, or namefastcmp_c, all of which use
1892  * memcmp() rather than strcoll().
1893  */
1894  if (lc_collate_is_c(collid))
1895  {
1896  if (typid == BPCHAROID)
1897  ssup->comparator = bpcharfastcmp_c;
1898  else if (typid == NAMEOID)
1899  {
1900  ssup->comparator = namefastcmp_c;
1901  /* Not supporting abbreviation with type NAME, for now */
1902  abbreviate = false;
1903  }
1904  else
1905  ssup->comparator = varstrfastcmp_c;
1906 
1907  collate_c = true;
1908  }
1909  else
1910  {
1911  /*
1912  * We need a collation-sensitive comparison. To make things faster,
1913  * we'll figure out the collation based on the locale id and cache the
1914  * result.
1915  */
1917 
1918  /*
1919  * We use varlenafastcmp_locale except for type NAME.
1920  */
1921  if (typid == NAMEOID)
1922  {
1924  /* Not supporting abbreviation with type NAME, for now */
1925  abbreviate = false;
1926  }
1927  else
1929  }
1930 
1931  /*
1932  * Unfortunately, it seems that abbreviation for non-C collations is
1933  * broken on many common platforms; see pg_strxfrm_enabled().
1934  *
1935  * Even apart from the risk of broken locales, it's possible that there
1936  * are platforms where the use of abbreviated keys should be disabled at
1937  * compile time. Having only 4 byte datums could make worst-case
1938  * performance drastically more likely, for example. Moreover, macOS's
1939  * strxfrm() implementation is known to not effectively concentrate a
1940  * significant amount of entropy from the original string in earlier
1941  * transformed blobs. It's possible that other supported platforms are
1942  * similarly encumbered. So, if we ever get past disabling this
1943  * categorically, we may still want or need to disable it for particular
1944  * platforms.
1945  */
1946  if (!collate_c && !pg_strxfrm_enabled(locale))
1947  abbreviate = false;
1948 
1949  /*
1950  * If we're using abbreviated keys, or if we're using a locale-aware
1951  * comparison, we need to initialize a VarStringSortSupport object. Both
1952  * cases will make use of the temporary buffers we initialize here for
1953  * scratch space (and to detect requirement for BpChar semantics from
1954  * caller), and the abbreviation case requires additional state.
1955  */
1956  if (abbreviate || !collate_c)
1957  {
1958  sss = palloc(sizeof(VarStringSortSupport));
1959  sss->buf1 = palloc(TEXTBUFLEN);
1960  sss->buflen1 = TEXTBUFLEN;
1961  sss->buf2 = palloc(TEXTBUFLEN);
1962  sss->buflen2 = TEXTBUFLEN;
1963  /* Start with invalid values */
1964  sss->last_len1 = -1;
1965  sss->last_len2 = -1;
1966  /* Initialize */
1967  sss->last_returned = 0;
1968  sss->locale = locale;
1969 
1970  /*
1971  * To avoid somehow confusing a strxfrm() blob and an original string,
1972  * constantly keep track of the variety of data that buf1 and buf2
1973  * currently contain.
1974  *
1975  * Comparisons may be interleaved with conversion calls. Frequently,
1976  * conversions and comparisons are batched into two distinct phases,
1977  * but the correctness of caching cannot hinge upon this. For
1978  * comparison caching, buffer state is only trusted if cache_blob is
1979  * found set to false, whereas strxfrm() caching only trusts the state
1980  * when cache_blob is found set to true.
1981  *
1982  * Arbitrarily initialize cache_blob to true.
1983  */
1984  sss->cache_blob = true;
1985  sss->collate_c = collate_c;
1986  sss->typid = typid;
1987  ssup->ssup_extra = sss;
1988 
1989  /*
1990  * If possible, plan to use the abbreviated keys optimization. The
1991  * core code may switch back to authoritative comparator should
1992  * abbreviation be aborted.
1993  */
1994  if (abbreviate)
1995  {
1996  sss->prop_card = 0.20;
1997  initHyperLogLog(&sss->abbr_card, 10);
1998  initHyperLogLog(&sss->full_card, 10);
1999  ssup->abbrev_full_comparator = ssup->comparator;
2003  }
2004  }
2005 }
2006 
2007 /*
2008  * sortsupport comparison func (for C locale case)
2009  */
2010 static int
2012 {
2013  VarString *arg1 = DatumGetVarStringPP(x);
2014  VarString *arg2 = DatumGetVarStringPP(y);
2015  char *a1p,
2016  *a2p;
2017  int len1,
2018  len2,
2019  result;
2020 
2021  a1p = VARDATA_ANY(arg1);
2022  a2p = VARDATA_ANY(arg2);
2023 
2024  len1 = VARSIZE_ANY_EXHDR(arg1);
2025  len2 = VARSIZE_ANY_EXHDR(arg2);
2026 
2027  result = memcmp(a1p, a2p, Min(len1, len2));
2028  if ((result == 0) && (len1 != len2))
2029  result = (len1 < len2) ? -1 : 1;
2030 
2031  /* We can't afford to leak memory here. */
2032  if (PointerGetDatum(arg1) != x)
2033  pfree(arg1);
2034  if (PointerGetDatum(arg2) != y)
2035  pfree(arg2);
2036 
2037  return result;
2038 }
2039 
2040 /*
2041  * sortsupport comparison func (for BpChar C locale case)
2042  *
2043  * BpChar outsources its sortsupport to this module. Specialization for the
2044  * varstr_sortsupport BpChar case, modeled on
2045  * internal_bpchar_pattern_compare().
2046  */
2047 static int
2049 {
2050  BpChar *arg1 = DatumGetBpCharPP(x);
2051  BpChar *arg2 = DatumGetBpCharPP(y);
2052  char *a1p,
2053  *a2p;
2054  int len1,
2055  len2,
2056  result;
2057 
2058  a1p = VARDATA_ANY(arg1);
2059  a2p = VARDATA_ANY(arg2);
2060 
2061  len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2062  len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2063 
2064  result = memcmp(a1p, a2p, Min(len1, len2));
2065  if ((result == 0) && (len1 != len2))
2066  result = (len1 < len2) ? -1 : 1;
2067 
2068  /* We can't afford to leak memory here. */
2069  if (PointerGetDatum(arg1) != x)
2070  pfree(arg1);
2071  if (PointerGetDatum(arg2) != y)
2072  pfree(arg2);
2073 
2074  return result;
2075 }
2076 
2077 /*
2078  * sortsupport comparison func (for NAME C locale case)
2079  */
2080 static int
2082 {
2083  Name arg1 = DatumGetName(x);
2084  Name arg2 = DatumGetName(y);
2085 
2086  return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2087 }
2088 
2089 /*
2090  * sortsupport comparison func (for locale case with all varlena types)
2091  */
2092 static int
2094 {
2095  VarString *arg1 = DatumGetVarStringPP(x);
2096  VarString *arg2 = DatumGetVarStringPP(y);
2097  char *a1p,
2098  *a2p;
2099  int len1,
2100  len2,
2101  result;
2102 
2103  a1p = VARDATA_ANY(arg1);
2104  a2p = VARDATA_ANY(arg2);
2105 
2106  len1 = VARSIZE_ANY_EXHDR(arg1);
2107  len2 = VARSIZE_ANY_EXHDR(arg2);
2108 
2109  result = varstrfastcmp_locale(a1p, len1, a2p, len2, ssup);
2110 
2111  /* We can't afford to leak memory here. */
2112  if (PointerGetDatum(arg1) != x)
2113  pfree(arg1);
2114  if (PointerGetDatum(arg2) != y)
2115  pfree(arg2);
2116 
2117  return result;
2118 }
2119 
2120 /*
2121  * sortsupport comparison func (for locale case with NAME type)
2122  */
2123 static int
2125 {
2126  Name arg1 = DatumGetName(x);
2127  Name arg2 = DatumGetName(y);
2128 
2129  return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)),
2130  NameStr(*arg2), strlen(NameStr(*arg2)),
2131  ssup);
2132 }
2133 
2134 /*
2135  * sortsupport comparison func for locale cases
2136  */
2137 static int
2138 varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
2139 {
2141  int result;
2142  bool arg1_match;
2143 
2144  /* Fast pre-check for equality, as discussed in varstr_cmp() */
2145  if (len1 == len2 && memcmp(a1p, a2p, len1) == 0)
2146  {
2147  /*
2148  * No change in buf1 or buf2 contents, so avoid changing last_len1 or
2149  * last_len2. Existing contents of buffers might still be used by
2150  * next call.
2151  *
2152  * It's fine to allow the comparison of BpChar padding bytes here,
2153  * even though that implies that the memcmp() will usually be
2154  * performed for BpChar callers (though multibyte characters could
2155  * still prevent that from occurring). The memcmp() is still very
2156  * cheap, and BpChar's funny semantics have us remove trailing spaces
2157  * (not limited to padding), so we need make no distinction between
2158  * padding space characters and "real" space characters.
2159  */
2160  return 0;
2161  }
2162 
2163  if (sss->typid == BPCHAROID)
2164  {
2165  /* Get true number of bytes, ignoring trailing spaces */
2166  len1 = bpchartruelen(a1p, len1);
2167  len2 = bpchartruelen(a2p, len2);
2168  }
2169 
2170  if (len1 >= sss->buflen1)
2171  {
2172  sss->buflen1 = Max(len1 + 1, Min(sss->buflen1 * 2, MaxAllocSize));
2173  sss->buf1 = repalloc(sss->buf1, sss->buflen1);
2174  }
2175  if (len2 >= sss->buflen2)
2176  {
2177  sss->buflen2 = Max(len2 + 1, Min(sss->buflen2 * 2, MaxAllocSize));
2178  sss->buf2 = repalloc(sss->buf2, sss->buflen2);
2179  }
2180 
2181  /*
2182  * We're likely to be asked to compare the same strings repeatedly, and
2183  * memcmp() is so much cheaper than strcoll() that it pays to try to cache
2184  * comparisons, even though in general there is no reason to think that
2185  * that will work out (every string datum may be unique). Caching does
2186  * not slow things down measurably when it doesn't work out, and can speed
2187  * things up by rather a lot when it does. In part, this is because the
2188  * memcmp() compares data from cachelines that are needed in L1 cache even
2189  * when the last comparison's result cannot be reused.
2190  */
2191  arg1_match = true;
2192  if (len1 != sss->last_len1 || memcmp(sss->buf1, a1p, len1) != 0)
2193  {
2194  arg1_match = false;
2195  memcpy(sss->buf1, a1p, len1);
2196  sss->buf1[len1] = '\0';
2197  sss->last_len1 = len1;
2198  }
2199 
2200  /*
2201  * If we're comparing the same two strings as last time, we can return the
2202  * same answer without calling strcoll() again. This is more likely than
2203  * it seems (at least with moderate to low cardinality sets), because
2204  * quicksort compares the same pivot against many values.
2205  */
2206  if (len2 != sss->last_len2 || memcmp(sss->buf2, a2p, len2) != 0)
2207  {
2208  memcpy(sss->buf2, a2p, len2);
2209  sss->buf2[len2] = '\0';
2210  sss->last_len2 = len2;
2211  }
2212  else if (arg1_match && !sss->cache_blob)
2213  {
2214  /* Use result cached following last actual strcoll() call */
2215  return sss->last_returned;
2216  }
2217 
2218  result = pg_strcoll(sss->buf1, sss->buf2, sss->locale);
2219 
2220  /* Break tie if necessary. */
2221  if (result == 0 && pg_locale_deterministic(sss->locale))
2222  result = strcmp(sss->buf1, sss->buf2);
2223 
2224  /* Cache result, perhaps saving an expensive strcoll() call next time */
2225  sss->cache_blob = false;
2226  sss->last_returned = result;
2227  return result;
2228 }
2229 
2230 /*
2231  * Conversion routine for sortsupport. Converts original to abbreviated key
2232  * representation. Our encoding strategy is simple -- pack the first 8 bytes
2233  * of a strxfrm() blob into a Datum (on little-endian machines, the 8 bytes are
2234  * stored in reverse order), and treat it as an unsigned integer. When the "C"
2235  * locale is used, or in case of bytea, just memcpy() from original instead.
2236  */
2237 static Datum
2239 {
2240  const size_t max_prefix_bytes = sizeof(Datum);
2242  VarString *authoritative = DatumGetVarStringPP(original);
2243  char *authoritative_data = VARDATA_ANY(authoritative);
2244 
2245  /* working state */
2246  Datum res;
2247  char *pres;
2248  int len;
2249  uint32 hash;
2250 
2251  pres = (char *) &res;
2252  /* memset(), so any non-overwritten bytes are NUL */
2253  memset(pres, 0, max_prefix_bytes);
2254  len = VARSIZE_ANY_EXHDR(authoritative);
2255 
2256  /* Get number of bytes, ignoring trailing spaces */
2257  if (sss->typid == BPCHAROID)
2258  len = bpchartruelen(authoritative_data, len);
2259 
2260  /*
2261  * If we're using the C collation, use memcpy(), rather than strxfrm(), to
2262  * abbreviate keys. The full comparator for the C locale is always
2263  * memcmp(). It would be incorrect to allow bytea callers (callers that
2264  * always force the C collation -- bytea isn't a collatable type, but this
2265  * approach is convenient) to use strxfrm(). This is because bytea
2266  * strings may contain NUL bytes. Besides, this should be faster, too.
2267  *
2268  * More generally, it's okay that bytea callers can have NUL bytes in
2269  * strings because abbreviated cmp need not make a distinction between
2270  * terminating NUL bytes, and NUL bytes representing actual NULs in the
2271  * authoritative representation. Hopefully a comparison at or past one
2272  * abbreviated key's terminating NUL byte will resolve the comparison
2273  * without consulting the authoritative representation; specifically, some
2274  * later non-NUL byte in the longer string can resolve the comparison
2275  * against a subsequent terminating NUL in the shorter string. There will
2276  * usually be what is effectively a "length-wise" resolution there and
2277  * then.
2278  *
2279  * If that doesn't work out -- if all bytes in the longer string
2280  * positioned at or past the offset of the smaller string's (first)
2281  * terminating NUL are actually representative of NUL bytes in the
2282  * authoritative binary string (perhaps with some *terminating* NUL bytes
2283  * towards the end of the longer string iff it happens to still be small)
2284  * -- then an authoritative tie-breaker will happen, and do the right
2285  * thing: explicitly consider string length.
2286  */
2287  if (sss->collate_c)
2288  memcpy(pres, authoritative_data, Min(len, max_prefix_bytes));
2289  else
2290  {
2291  Size bsize;
2292 
2293  /*
2294  * We're not using the C collation, so fall back on strxfrm or ICU
2295  * analogs.
2296  */
2297 
2298  /* By convention, we use buffer 1 to store and NUL-terminate */
2299  if (len >= sss->buflen1)
2300  {
2301  sss->buflen1 = Max(len + 1, Min(sss->buflen1 * 2, MaxAllocSize));
2302  sss->buf1 = repalloc(sss->buf1, sss->buflen1);
2303  }
2304 
2305  /* Might be able to reuse strxfrm() blob from last call */
2306  if (sss->last_len1 == len && sss->cache_blob &&
2307  memcmp(sss->buf1, authoritative_data, len) == 0)
2308  {
2309  memcpy(pres, sss->buf2, Min(max_prefix_bytes, sss->last_len2));
2310  /* No change affecting cardinality, so no hashing required */
2311  goto done;
2312  }
2313 
2314  memcpy(sss->buf1, authoritative_data, len);
2315 
2316  /*
2317  * pg_strxfrm() and pg_strxfrm_prefix expect NUL-terminated strings.
2318  */
2319  sss->buf1[len] = '\0';
2320  sss->last_len1 = len;
2321 
2323  {
2324  if (sss->buflen2 < max_prefix_bytes)
2325  {
2326  sss->buflen2 = Max(max_prefix_bytes,
2327  Min(sss->buflen2 * 2, MaxAllocSize));
2328  sss->buf2 = repalloc(sss->buf2, sss->buflen2);
2329  }
2330 
2331  bsize = pg_strxfrm_prefix(sss->buf2, sss->buf1,
2332  max_prefix_bytes, sss->locale);
2333  sss->last_len2 = bsize;
2334  }
2335  else
2336  {
2337  /*
2338  * Loop: Call pg_strxfrm(), possibly enlarge buffer, and try
2339  * again. The pg_strxfrm() function leaves the result buffer
2340  * content undefined if the result did not fit, so we need to
2341  * retry until everything fits, even though we only need the first
2342  * few bytes in the end.
2343  */
2344  for (;;)
2345  {
2346  bsize = pg_strxfrm(sss->buf2, sss->buf1, sss->buflen2,
2347  sss->locale);
2348 
2349  sss->last_len2 = bsize;
2350  if (bsize < sss->buflen2)
2351  break;
2352 
2353  /*
2354  * Grow buffer and retry.
2355  */
2356  sss->buflen2 = Max(bsize + 1,
2357  Min(sss->buflen2 * 2, MaxAllocSize));
2358  sss->buf2 = repalloc(sss->buf2, sss->buflen2);
2359  }
2360  }
2361 
2362  /*
2363  * Every Datum byte is always compared. This is safe because the
2364  * strxfrm() blob is itself NUL terminated, leaving no danger of
2365  * misinterpreting any NUL bytes not intended to be interpreted as
2366  * logically representing termination.
2367  *
2368  * (Actually, even if there were NUL bytes in the blob it would be
2369  * okay. See remarks on bytea case above.)
2370  */
2371  memcpy(pres, sss->buf2, Min(max_prefix_bytes, bsize));
2372  }
2373 
2374  /*
2375  * Maintain approximate cardinality of both abbreviated keys and original,
2376  * authoritative keys using HyperLogLog. Used as cheap insurance against
2377  * the worst case, where we do many string transformations for no saving
2378  * in full strcoll()-based comparisons. These statistics are used by
2379  * varstr_abbrev_abort().
2380  *
2381  * First, Hash key proper, or a significant fraction of it. Mix in length
2382  * in order to compensate for cases where differences are past
2383  * PG_CACHE_LINE_SIZE bytes, so as to limit the overhead of hashing.
2384  */
2385  hash = DatumGetUInt32(hash_any((unsigned char *) authoritative_data,
2387 
2388  if (len > PG_CACHE_LINE_SIZE)
2390 
2391  addHyperLogLog(&sss->full_card, hash);
2392 
2393  /* Hash abbreviated key */
2394 #if SIZEOF_DATUM == 8
2395  {
2396  uint32 lohalf,
2397  hihalf;
2398 
2399  lohalf = (uint32) res;
2400  hihalf = (uint32) (res >> 32);
2401  hash = DatumGetUInt32(hash_uint32(lohalf ^ hihalf));
2402  }
2403 #else /* SIZEOF_DATUM != 8 */
2405 #endif
2406 
2407  addHyperLogLog(&sss->abbr_card, hash);
2408 
2409  /* Cache result, perhaps saving an expensive strxfrm() call next time */
2410  sss->cache_blob = true;
2411 done:
2412 
2413  /*
2414  * Byteswap on little-endian machines.
2415  *
2416  * This is needed so that ssup_datum_unsigned_cmp() (an unsigned integer
2417  * 3-way comparator) works correctly on all platforms. If we didn't do
2418  * this, the comparator would have to call memcmp() with a pair of
2419  * pointers to the first byte of each abbreviated key, which is slower.
2420  */
2421  res = DatumBigEndianToNative(res);
2422 
2423  /* Don't leak memory here */
2424  if (PointerGetDatum(authoritative) != original)
2425  pfree(authoritative);
2426 
2427  return res;
2428 }
2429 
2430 /*
2431  * Callback for estimating effectiveness of abbreviated key optimization, using
2432  * heuristic rules. Returns value indicating if the abbreviation optimization
2433  * should be aborted, based on its projected effectiveness.
2434  */
2435 static bool
2436 varstr_abbrev_abort(int memtupcount, SortSupport ssup)
2437 {
2439  double abbrev_distinct,
2440  key_distinct;
2441 
2442  Assert(ssup->abbreviate);
2443 
2444  /* Have a little patience */
2445  if (memtupcount < 100)
2446  return false;
2447 
2448  abbrev_distinct = estimateHyperLogLog(&sss->abbr_card);
2449  key_distinct = estimateHyperLogLog(&sss->full_card);
2450 
2451  /*
2452  * Clamp cardinality estimates to at least one distinct value. While
2453  * NULLs are generally disregarded, if only NULL values were seen so far,
2454  * that might misrepresent costs if we failed to clamp.
2455  */
2456  if (abbrev_distinct <= 1.0)
2457  abbrev_distinct = 1.0;
2458 
2459  if (key_distinct <= 1.0)
2460  key_distinct = 1.0;
2461 
2462  /*
2463  * In the worst case all abbreviated keys are identical, while at the same
2464  * time there are differences within full key strings not captured in
2465  * abbreviations.
2466  */
2467 #ifdef TRACE_SORT
2468  if (trace_sort)
2469  {
2470  double norm_abbrev_card = abbrev_distinct / (double) memtupcount;
2471 
2472  elog(LOG, "varstr_abbrev: abbrev_distinct after %d: %f "
2473  "(key_distinct: %f, norm_abbrev_card: %f, prop_card: %f)",
2474  memtupcount, abbrev_distinct, key_distinct, norm_abbrev_card,
2475  sss->prop_card);
2476  }
2477 #endif
2478 
2479  /*
2480  * If the number of distinct abbreviated keys approximately matches the
2481  * number of distinct authoritative original keys, that's reason enough to
2482  * proceed. We can win even with a very low cardinality set if most
2483  * tie-breakers only memcmp(). This is by far the most important
2484  * consideration.
2485  *
2486  * While comparisons that are resolved at the abbreviated key level are
2487  * considerably cheaper than tie-breakers resolved with memcmp(), both of
2488  * those two outcomes are so much cheaper than a full strcoll() once
2489  * sorting is underway that it doesn't seem worth it to weigh abbreviated
2490  * cardinality against the overall size of the set in order to more
2491  * accurately model costs. Assume that an abbreviated comparison, and an
2492  * abbreviated comparison with a cheap memcmp()-based authoritative
2493  * resolution are equivalent.
2494  */
2495  if (abbrev_distinct > key_distinct * sss->prop_card)
2496  {
2497  /*
2498  * When we have exceeded 10,000 tuples, decay required cardinality
2499  * aggressively for next call.
2500  *
2501  * This is useful because the number of comparisons required on
2502  * average increases at a linearithmic rate, and at roughly 10,000
2503  * tuples that factor will start to dominate over the linear costs of
2504  * string transformation (this is a conservative estimate). The decay
2505  * rate is chosen to be a little less aggressive than halving -- which
2506  * (since we're called at points at which memtupcount has doubled)
2507  * would never see the cost model actually abort past the first call
2508  * following a decay. This decay rate is mostly a precaution against
2509  * a sudden, violent swing in how well abbreviated cardinality tracks
2510  * full key cardinality. The decay also serves to prevent a marginal
2511  * case from being aborted too late, when too much has already been
2512  * invested in string transformation.
2513  *
2514  * It's possible for sets of several million distinct strings with
2515  * mere tens of thousands of distinct abbreviated keys to still
2516  * benefit very significantly. This will generally occur provided
2517  * each abbreviated key is a proxy for a roughly uniform number of the
2518  * set's full keys. If it isn't so, we hope to catch that early and
2519  * abort. If it isn't caught early, by the time the problem is
2520  * apparent it's probably not worth aborting.
2521  */
2522  if (memtupcount > 10000)
2523  sss->prop_card *= 0.65;
2524 
2525  return false;
2526  }
2527 
2528  /*
2529  * Abort abbreviation strategy.
2530  *
2531  * The worst case, where all abbreviated keys are identical while all
2532  * original strings differ will typically only see a regression of about
2533  * 10% in execution time for small to medium sized lists of strings.
2534  * Whereas on modern CPUs where cache stalls are the dominant cost, we can
2535  * often expect very large improvements, particularly with sets of strings
2536  * of moderately high to high abbreviated cardinality. There is little to
2537  * lose but much to gain, which our strategy reflects.
2538  */
2539 #ifdef TRACE_SORT
2540  if (trace_sort)
2541  elog(LOG, "varstr_abbrev: aborted abbreviation at %d "
2542  "(abbrev_distinct: %f, key_distinct: %f, prop_card: %f)",
2543  memtupcount, abbrev_distinct, key_distinct, sss->prop_card);
2544 #endif
2545 
2546  return true;
2547 }
2548 
2549 /*
2550  * Generic equalimage support function for character type's operator classes.
2551  * Disables the use of deduplication with nondeterministic collations.
2552  */
2553 Datum
2555 {
2556  /* Oid opcintype = PG_GETARG_OID(0); */
2558 
2560 
2561  if (lc_collate_is_c(collid) ||
2562  collid == DEFAULT_COLLATION_OID ||
2564  PG_RETURN_BOOL(true);
2565  else
2566  PG_RETURN_BOOL(false);
2567 }
2568 
2569 Datum
2571 {
2572  text *arg1 = PG_GETARG_TEXT_PP(0);
2573  text *arg2 = PG_GETARG_TEXT_PP(1);
2574  text *result;
2575 
2576  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2577 
2578  PG_RETURN_TEXT_P(result);
2579 }
2580 
2581 Datum
2583 {
2584  text *arg1 = PG_GETARG_TEXT_PP(0);
2585  text *arg2 = PG_GETARG_TEXT_PP(1);
2586  text *result;
2587 
2588  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0) ? arg1 : arg2);
2589 
2590  PG_RETURN_TEXT_P(result);
2591 }
2592 
2593 
2594 /*
2595  * Cross-type comparison functions for types text and name.
2596  */
2597 
2598 Datum
2600 {
2601  Name arg1 = PG_GETARG_NAME(0);
2602  text *arg2 = PG_GETARG_TEXT_PP(1);
2603  size_t len1 = strlen(NameStr(*arg1));
2604  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2606  bool result;
2607 
2609 
2610  if (collid == C_COLLATION_OID)
2611  result = (len1 == len2 &&
2612  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2613  else
2614  result = (varstr_cmp(NameStr(*arg1), len1,
2615  VARDATA_ANY(arg2), len2,
2616  collid) == 0);
2617 
2618  PG_FREE_IF_COPY(arg2, 1);
2619 
2620  PG_RETURN_BOOL(result);
2621 }
2622 
2623 Datum
2625 {
2626  text *arg1 = PG_GETARG_TEXT_PP(0);
2627  Name arg2 = PG_GETARG_NAME(1);
2628  size_t len1 = VARSIZE_ANY_EXHDR(arg1);
2629  size_t len2 = strlen(NameStr(*arg2));
2631  bool result;
2632 
2634 
2635  if (collid == C_COLLATION_OID)
2636  result = (len1 == len2 &&
2637  memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
2638  else
2639  result = (varstr_cmp(VARDATA_ANY(arg1), len1,
2640  NameStr(*arg2), len2,
2641  collid) == 0);
2642 
2643  PG_FREE_IF_COPY(arg1, 0);
2644 
2645  PG_RETURN_BOOL(result);
2646 }
2647 
2648 Datum
2650 {
2651  Name arg1 = PG_GETARG_NAME(0);
2652  text *arg2 = PG_GETARG_TEXT_PP(1);
2653  size_t len1 = strlen(NameStr(*arg1));
2654  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2656  bool result;
2657 
2659 
2660  if (collid == C_COLLATION_OID)
2661  result = !(len1 == len2 &&
2662  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2663  else
2664  result = !(varstr_cmp(NameStr(*arg1), len1,
2665  VARDATA_ANY(arg2), len2,
2666  collid) == 0);
2667 
2668  PG_FREE_IF_COPY(arg2, 1);
2669 
2670  PG_RETURN_BOOL(result);
2671 }
2672 
2673 Datum
2675 {
2676  text *arg1 = PG_GETARG_TEXT_PP(0);
2677  Name arg2 = PG_GETARG_NAME(1);
2678  size_t len1 = VARSIZE_ANY_EXHDR(arg1);
2679  size_t len2 = strlen(NameStr(*arg2));
2681  bool result;
2682 
2684 
2685  if (collid == C_COLLATION_OID)
2686  result = !(len1 == len2 &&
2687  memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
2688  else
2689  result = !(varstr_cmp(VARDATA_ANY(arg1), len1,
2690  NameStr(*arg2), len2,
2691  collid) == 0);
2692 
2693  PG_FREE_IF_COPY(arg1, 0);
2694 
2695  PG_RETURN_BOOL(result);
2696 }
2697 
2698 Datum
2700 {
2701  Name arg1 = PG_GETARG_NAME(0);
2702  text *arg2 = PG_GETARG_TEXT_PP(1);
2703  int32 result;
2704 
2705  result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
2706  VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
2707  PG_GET_COLLATION());
2708 
2709  PG_FREE_IF_COPY(arg2, 1);
2710 
2711  PG_RETURN_INT32(result);
2712 }
2713 
2714 Datum
2716 {
2717  text *arg1 = PG_GETARG_TEXT_PP(0);
2718  Name arg2 = PG_GETARG_NAME(1);
2719  int32 result;
2720 
2721  result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
2722  NameStr(*arg2), strlen(NameStr(*arg2)),
2723  PG_GET_COLLATION());
2724 
2725  PG_FREE_IF_COPY(arg1, 0);
2726 
2727  PG_RETURN_INT32(result);
2728 }
2729 
2730 #define CmpCall(cmpfunc) \
2731  DatumGetInt32(DirectFunctionCall2Coll(cmpfunc, \
2732  PG_GET_COLLATION(), \
2733  PG_GETARG_DATUM(0), \
2734  PG_GETARG_DATUM(1)))
2735 
2736 Datum
2738 {
2740 }
2741 
2742 Datum
2744 {
2746 }
2747 
2748 Datum
2750 {
2752 }
2753 
2754 Datum
2756 {
2758 }
2759 
2760 Datum
2762 {
2764 }
2765 
2766 Datum
2768 {
2770 }
2771 
2772 Datum
2774 {
2776 }
2777 
2778 Datum
2780 {
2782 }
2783 
2784 #undef CmpCall
2785 
2786 
2787 /*
2788  * The following operators support character-by-character comparison
2789  * of text datums, to allow building indexes suitable for LIKE clauses.
2790  * Note that the regular texteq/textne comparison operators, and regular
2791  * support functions 1 and 2 with "C" collation are assumed to be
2792  * compatible with these!
2793  */
2794 
2795 static int
2797 {
2798  int result;
2799  int len1,
2800  len2;
2801 
2802  len1 = VARSIZE_ANY_EXHDR(arg1);
2803  len2 = VARSIZE_ANY_EXHDR(arg2);
2804 
2805  result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
2806  if (result != 0)
2807  return result;
2808  else if (len1 < len2)
2809  return -1;
2810  else if (len1 > len2)
2811  return 1;
2812  else
2813  return 0;
2814 }
2815 
2816 
2817 Datum
2819 {
2820  text *arg1 = PG_GETARG_TEXT_PP(0);
2821  text *arg2 = PG_GETARG_TEXT_PP(1);
2822  int result;
2823 
2824  result = internal_text_pattern_compare(arg1, arg2);
2825 
2826  PG_FREE_IF_COPY(arg1, 0);
2827  PG_FREE_IF_COPY(arg2, 1);
2828 
2829  PG_RETURN_BOOL(result < 0);
2830 }
2831 
2832 
2833 Datum
2835 {
2836  text *arg1 = PG_GETARG_TEXT_PP(0);
2837  text *arg2 = PG_GETARG_TEXT_PP(1);
2838  int result;
2839 
2840  result = internal_text_pattern_compare(arg1, arg2);
2841 
2842  PG_FREE_IF_COPY(arg1, 0);
2843  PG_FREE_IF_COPY(arg2, 1);
2844 
2845  PG_RETURN_BOOL(result <= 0);
2846 }
2847 
2848 
2849 Datum
2851 {
2852  text *arg1 = PG_GETARG_TEXT_PP(0);
2853  text *arg2 = PG_GETARG_TEXT_PP(1);
2854  int result;
2855 
2856  result = internal_text_pattern_compare(arg1, arg2);
2857 
2858  PG_FREE_IF_COPY(arg1, 0);
2859  PG_FREE_IF_COPY(arg2, 1);
2860 
2861  PG_RETURN_BOOL(result >= 0);
2862 }
2863 
2864 
2865 Datum
2867 {
2868  text *arg1 = PG_GETARG_TEXT_PP(0);
2869  text *arg2 = PG_GETARG_TEXT_PP(1);
2870  int result;
2871 
2872  result = internal_text_pattern_compare(arg1, arg2);
2873 
2874  PG_FREE_IF_COPY(arg1, 0);
2875  PG_FREE_IF_COPY(arg2, 1);
2876 
2877  PG_RETURN_BOOL(result > 0);
2878 }
2879 
2880 
2881 Datum
2883 {
2884  text *arg1 = PG_GETARG_TEXT_PP(0);
2885  text *arg2 = PG_GETARG_TEXT_PP(1);
2886  int result;
2887 
2888  result = internal_text_pattern_compare(arg1, arg2);
2889 
2890  PG_FREE_IF_COPY(arg1, 0);
2891  PG_FREE_IF_COPY(arg2, 1);
2892 
2893  PG_RETURN_INT32(result);
2894 }
2895 
2896 
2897 Datum
2899 {
2901  MemoryContext oldcontext;
2902 
2903  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2904 
2905  /* Use generic string SortSupport, forcing "C" collation */
2906  varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID);
2907 
2908  MemoryContextSwitchTo(oldcontext);
2909 
2910  PG_RETURN_VOID();
2911 }
2912 
2913 
2914 /*-------------------------------------------------------------
2915  * byteaoctetlen
2916  *
2917  * get the number of bytes contained in an instance of type 'bytea'
2918  *-------------------------------------------------------------
2919  */
2920 Datum
2922 {
2923  Datum str = PG_GETARG_DATUM(0);
2924 
2925  /* We need not detoast the input at all */
2927 }
2928 
2929 /*
2930  * byteacat -
2931  * takes two bytea* and returns a bytea* that is the concatenation of
2932  * the two.
2933  *
2934  * Cloned from textcat and modified as required.
2935  */
2936 Datum
2938 {
2939  bytea *t1 = PG_GETARG_BYTEA_PP(0);
2940  bytea *t2 = PG_GETARG_BYTEA_PP(1);
2941 
2943 }
2944 
2945 /*
2946  * bytea_catenate
2947  * Guts of byteacat(), broken out so it can be used by other functions
2948  *
2949  * Arguments can be in short-header form, but not compressed or out-of-line
2950  */
2951 static bytea *
2953 {
2954  bytea *result;
2955  int len1,
2956  len2,
2957  len;
2958  char *ptr;
2959 
2960  len1 = VARSIZE_ANY_EXHDR(t1);
2961  len2 = VARSIZE_ANY_EXHDR(t2);
2962 
2963  /* paranoia ... probably should throw error instead? */
2964  if (len1 < 0)
2965  len1 = 0;
2966  if (len2 < 0)
2967  len2 = 0;
2968 
2969  len = len1 + len2 + VARHDRSZ;
2970  result = (bytea *) palloc(len);
2971 
2972  /* Set size of result string... */
2973  SET_VARSIZE(result, len);
2974 
2975  /* Fill data field of result string... */
2976  ptr = VARDATA(result);
2977  if (len1 > 0)
2978  memcpy(ptr, VARDATA_ANY(t1), len1);
2979  if (len2 > 0)
2980  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
2981 
2982  return result;
2983 }
2984 
2985 #define PG_STR_GET_BYTEA(str_) \
2986  DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
2987 
2988 /*
2989  * bytea_substr()
2990  * Return a substring starting at the specified position.
2991  * Cloned from text_substr and modified as required.
2992  *
2993  * Input:
2994  * - string
2995  * - starting position (is one-based)
2996  * - string length (optional)
2997  *
2998  * If the starting position is zero or less, then return from the start of the string
2999  * adjusting the length to be consistent with the "negative start" per SQL.
3000  * If the length is less than zero, an ERROR is thrown. If no third argument
3001  * (length) is provided, the length to the end of the string is assumed.
3002  */
3003 Datum
3005 {
3007  PG_GETARG_INT32(1),
3008  PG_GETARG_INT32(2),
3009  false));
3010 }
3011 
3012 /*
3013  * bytea_substr_no_len -
3014  * Wrapper to avoid opr_sanity failure due to
3015  * one function accepting a different number of args.
3016  */
3017 Datum
3019 {
3021  PG_GETARG_INT32(1),
3022  -1,
3023  true));
3024 }
3025 
3026 static bytea *
3028  int S,
3029  int L,
3030  bool length_not_specified)
3031 {
3032  int32 S1; /* adjusted start position */
3033  int32 L1; /* adjusted substring length */
3034  int32 E; /* end position */
3035 
3036  /*
3037  * The logic here should generally match text_substring().
3038  */
3039  S1 = Max(S, 1);
3040 
3041  if (length_not_specified)
3042  {
3043  /*
3044  * Not passed a length - DatumGetByteaPSlice() grabs everything to the
3045  * end of the string if we pass it a negative value for length.
3046  */
3047  L1 = -1;
3048  }
3049  else if (L < 0)
3050  {
3051  /* SQL99 says to throw an error for E < S, i.e., negative length */
3052  ereport(ERROR,
3053  (errcode(ERRCODE_SUBSTRING_ERROR),
3054  errmsg("negative substring length not allowed")));
3055  L1 = -1; /* silence stupider compilers */
3056  }
3057  else if (pg_add_s32_overflow(S, L, &E))
3058  {
3059  /*
3060  * L could be large enough for S + L to overflow, in which case the
3061  * substring must run to end of string.
3062  */
3063  L1 = -1;
3064  }
3065  else
3066  {
3067  /*
3068  * A zero or negative value for the end position can happen if the
3069  * start was negative or one. SQL99 says to return a zero-length
3070  * string.
3071  */
3072  if (E < 1)
3073  return PG_STR_GET_BYTEA("");
3074 
3075  L1 = E - S1;
3076  }
3077 
3078  /*
3079  * If the start position is past the end of the string, SQL99 says to
3080  * return a zero-length string -- DatumGetByteaPSlice() will do that for
3081  * us. We need only convert S1 to zero-based starting position.
3082  */
3083  return DatumGetByteaPSlice(str, S1 - 1, L1);
3084 }
3085 
3086 /*
3087  * byteaoverlay
3088  * Replace specified substring of first string with second
3089  *
3090  * The SQL standard defines OVERLAY() in terms of substring and concatenation.
3091  * This code is a direct implementation of what the standard says.
3092  */
3093 Datum
3095 {
3096  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3097  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3098  int sp = PG_GETARG_INT32(2); /* substring start position */
3099  int sl = PG_GETARG_INT32(3); /* substring length */
3100 
3101  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3102 }
3103 
3104 Datum
3106 {
3107  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3108  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3109  int sp = PG_GETARG_INT32(2); /* substring start position */
3110  int sl;
3111 
3112  sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
3113  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3114 }
3115 
3116 static bytea *
3117 bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
3118 {
3119  bytea *result;
3120  bytea *s1;
3121  bytea *s2;
3122  int sp_pl_sl;
3123 
3124  /*
3125  * Check for possible integer-overflow cases. For negative sp, throw a
3126  * "substring length" error because that's what should be expected
3127  * according to the spec's definition of OVERLAY().
3128  */
3129  if (sp <= 0)
3130  ereport(ERROR,
3131  (errcode(ERRCODE_SUBSTRING_ERROR),
3132  errmsg("negative substring length not allowed")));
3133  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
3134  ereport(ERROR,
3135  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3136  errmsg("integer out of range")));
3137 
3138  s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
3139  s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
3140  result = bytea_catenate(s1, t2);
3141  result = bytea_catenate(result, s2);
3142 
3143  return result;
3144 }
3145 
3146 /*
3147  * bit_count
3148  */
3149 Datum
3151 {
3152  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3153 
3155 }
3156 
3157 /*
3158  * byteapos -
3159  * Return the position of the specified substring.
3160  * Implements the SQL POSITION() function.
3161  * Cloned from textpos and modified as required.
3162  */
3163 Datum
3165 {
3166  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3167  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3168  int pos;
3169  int px,
3170  p;
3171  int len1,
3172  len2;
3173  char *p1,
3174  *p2;
3175 
3176  len1 = VARSIZE_ANY_EXHDR(t1);
3177  len2 = VARSIZE_ANY_EXHDR(t2);
3178 
3179  if (len2 <= 0)
3180  PG_RETURN_INT32(1); /* result for empty pattern */
3181 
3182  p1 = VARDATA_ANY(t1);
3183  p2 = VARDATA_ANY(t2);
3184 
3185  pos = 0;
3186  px = (len1 - len2);
3187  for (p = 0; p <= px; p++)
3188  {
3189  if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
3190  {
3191  pos = p + 1;
3192  break;
3193  };
3194  p1++;
3195  };
3196 
3197  PG_RETURN_INT32(pos);
3198 }
3199 
3200 /*-------------------------------------------------------------
3201  * byteaGetByte
3202  *
3203  * this routine treats "bytea" as an array of bytes.
3204  * It returns the Nth byte (a number between 0 and 255).
3205  *-------------------------------------------------------------
3206  */
3207 Datum
3209 {
3210  bytea *v = PG_GETARG_BYTEA_PP(0);
3211  int32 n = PG_GETARG_INT32(1);
3212  int len;
3213  int byte;
3214 
3215  len = VARSIZE_ANY_EXHDR(v);
3216 
3217  if (n < 0 || n >= len)
3218  ereport(ERROR,
3219  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3220  errmsg("index %d out of valid range, 0..%d",
3221  n, len - 1)));
3222 
3223  byte = ((unsigned char *) VARDATA_ANY(v))[n];
3224 
3225  PG_RETURN_INT32(byte);
3226 }
3227 
3228 /*-------------------------------------------------------------
3229  * byteaGetBit
3230  *
3231  * This routine treats a "bytea" type like an array of bits.
3232  * It returns the value of the Nth bit (0 or 1).
3233  *
3234  *-------------------------------------------------------------
3235  */
3236 Datum
3238 {
3239  bytea *v = PG_GETARG_BYTEA_PP(0);
3240  int64 n = PG_GETARG_INT64(1);
3241  int byteNo,
3242  bitNo;
3243  int len;
3244  int byte;
3245 
3246  len = VARSIZE_ANY_EXHDR(v);
3247 
3248  if (n < 0 || n >= (int64) len * 8)
3249  ereport(ERROR,
3250  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3251  errmsg("index %lld out of valid range, 0..%lld",
3252  (long long) n, (long long) len * 8 - 1)));
3253 
3254  /* n/8 is now known < len, so safe to cast to int */
3255  byteNo = (int) (n / 8);
3256  bitNo = (int) (n % 8);
3257 
3258  byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3259 
3260  if (byte & (1 << bitNo))
3261  PG_RETURN_INT32(1);
3262  else
3263  PG_RETURN_INT32(0);
3264 }
3265 
3266 /*-------------------------------------------------------------
3267  * byteaSetByte
3268  *
3269  * Given an instance of type 'bytea' creates a new one with
3270  * the Nth byte set to the given value.
3271  *
3272  *-------------------------------------------------------------
3273  */
3274 Datum
3276 {
3278  int32 n = PG_GETARG_INT32(1);
3279  int32 newByte = PG_GETARG_INT32(2);
3280  int len;
3281 
3282  len = VARSIZE(res) - VARHDRSZ;
3283 
3284  if (n < 0 || n >= len)
3285  ereport(ERROR,
3286  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3287  errmsg("index %d out of valid range, 0..%d",
3288  n, len - 1)));
3289 
3290  /*
3291  * Now set the byte.
3292  */
3293  ((unsigned char *) VARDATA(res))[n] = newByte;
3294 
3296 }
3297 
3298 /*-------------------------------------------------------------
3299  * byteaSetBit
3300  *
3301  * Given an instance of type 'bytea' creates a new one with
3302  * the Nth bit set to the given value.
3303  *
3304  *-------------------------------------------------------------
3305  */
3306 Datum
3308 {
3310  int64 n = PG_GETARG_INT64(1);
3311  int32 newBit = PG_GETARG_INT32(2);
3312  int len;
3313  int oldByte,
3314  newByte;
3315  int byteNo,
3316  bitNo;
3317 
3318  len = VARSIZE(res) - VARHDRSZ;
3319 
3320  if (n < 0 || n >= (int64) len * 8)
3321  ereport(ERROR,
3322  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3323  errmsg("index %lld out of valid range, 0..%lld",
3324  (long long) n, (long long) len * 8 - 1)));
3325 
3326  /* n/8 is now known < len, so safe to cast to int */
3327  byteNo = (int) (n / 8);
3328  bitNo = (int) (n % 8);
3329 
3330  /*
3331  * sanity check!
3332  */
3333  if (newBit != 0 && newBit != 1)
3334  ereport(ERROR,
3335  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3336  errmsg("new bit must be 0 or 1")));
3337 
3338  /*
3339  * Update the byte.
3340  */
3341  oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3342 
3343  if (newBit == 0)
3344  newByte = oldByte & (~(1 << bitNo));
3345  else
3346  newByte = oldByte | (1 << bitNo);
3347 
3348  ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3349 
3351 }
3352 
3353 
3354 /* text_name()
3355  * Converts a text type to a Name type.
3356  */
3357 Datum
3359 {
3360  text *s = PG_GETARG_TEXT_PP(0);
3361  Name result;
3362  int len;
3363 
3364  len = VARSIZE_ANY_EXHDR(s);
3365 
3366  /* Truncate oversize input */
3367  if (len >= NAMEDATALEN)
3369 
3370  /* We use palloc0 here to ensure result is zero-padded */
3371  result = (Name) palloc0(NAMEDATALEN);
3372  memcpy(NameStr(*result), VARDATA_ANY(s), len);
3373 
3374  PG_RETURN_NAME(result);
3375 }
3376 
3377 /* name_text()
3378  * Converts a Name type to a text type.
3379  */
3380 Datum
3382 {
3383  Name s = PG_GETARG_NAME(0);
3384 
3386 }
3387 
3388 
3389 /*
3390  * textToQualifiedNameList - convert a text object to list of names
3391  *
3392  * This implements the input parsing needed by nextval() and other
3393  * functions that take a text parameter representing a qualified name.
3394  * We split the name at dots, downcase if not double-quoted, and
3395  * truncate names if they're too long.
3396  */
3397 List *
3399 {
3400  char *rawname;
3401  List *result = NIL;
3402  List *namelist;
3403  ListCell *l;
3404 
3405  /* Convert to C string (handles possible detoasting). */
3406  /* Note we rely on being able to modify rawname below. */
3407  rawname = text_to_cstring(textval);
3408 
3409  if (!SplitIdentifierString(rawname, '.', &namelist))
3410  ereport(ERROR,
3411  (errcode(ERRCODE_INVALID_NAME),
3412  errmsg("invalid name syntax")));
3413 
3414  if (namelist == NIL)
3415  ereport(ERROR,
3416  (errcode(ERRCODE_INVALID_NAME),
3417  errmsg("invalid name syntax")));
3418 
3419  foreach(l, namelist)
3420  {
3421  char *curname = (char *) lfirst(l);
3422 
3423  result = lappend(result, makeString(pstrdup(curname)));
3424  }
3425 
3426  pfree(rawname);
3427  list_free(namelist);
3428 
3429  return result;
3430 }
3431 
3432 /*
3433  * SplitIdentifierString --- parse a string containing identifiers
3434  *
3435  * This is the guts of textToQualifiedNameList, and is exported for use in
3436  * other situations such as parsing GUC variables. In the GUC case, it's
3437  * important to avoid memory leaks, so the API is designed to minimize the
3438  * amount of stuff that needs to be allocated and freed.
3439  *
3440  * Inputs:
3441  * rawstring: the input string; must be overwritable! On return, it's
3442  * been modified to contain the separated identifiers.
3443  * separator: the separator punctuation expected between identifiers
3444  * (typically '.' or ','). Whitespace may also appear around
3445  * identifiers.
3446  * Outputs:
3447  * namelist: filled with a palloc'd list of pointers to identifiers within
3448  * rawstring. Caller should list_free() this even on error return.
3449  *
3450  * Returns true if okay, false if there is a syntax error in the string.
3451  *
3452  * Note that an empty string is considered okay here, though not in
3453  * textToQualifiedNameList.
3454  */
3455 bool
3456 SplitIdentifierString(char *rawstring, char separator,
3457  List **namelist)
3458 {
3459  char *nextp = rawstring;
3460  bool done = false;
3461 
3462  *namelist = NIL;
3463 
3464  while (scanner_isspace(*nextp))
3465  nextp++; /* skip leading whitespace */
3466 
3467  if (*nextp == '\0')
3468  return true; /* allow empty string */
3469 
3470  /* At the top of the loop, we are at start of a new identifier. */
3471  do
3472  {
3473  char *curname;
3474  char *endp;
3475 
3476  if (*nextp == '"')
3477  {
3478  /* Quoted name --- collapse quote-quote pairs, no downcasing */
3479  curname = nextp + 1;
3480  for (;;)
3481  {
3482  endp = strchr(nextp + 1, '"');
3483  if (endp == NULL)
3484  return false; /* mismatched quotes */
3485  if (endp[1] != '"')
3486  break; /* found end of quoted name */
3487  /* Collapse adjacent quotes into one quote, and look again */
3488  memmove(endp, endp + 1, strlen(endp));
3489  nextp = endp;
3490  }
3491  /* endp now points at the terminating quote */
3492  nextp = endp + 1;
3493  }
3494  else
3495  {
3496  /* Unquoted name --- extends to separator or whitespace */
3497  char *downname;
3498  int len;
3499 
3500  curname = nextp;
3501  while (*nextp && *nextp != separator &&
3502  !scanner_isspace(*nextp))
3503  nextp++;
3504  endp = nextp;
3505  if (curname == nextp)
3506  return false; /* empty unquoted name not allowed */
3507 
3508  /*
3509  * Downcase the identifier, using same code as main lexer does.
3510  *
3511  * XXX because we want to overwrite the input in-place, we cannot
3512  * support a downcasing transformation that increases the string
3513  * length. This is not a problem given the current implementation
3514  * of downcase_truncate_identifier, but we'll probably have to do
3515  * something about this someday.
3516  */
3517  len = endp - curname;
3518  downname = downcase_truncate_identifier(curname, len, false);
3519  Assert(strlen(downname) <= len);
3520  strncpy(curname, downname, len); /* strncpy is required here */
3521  pfree(downname);
3522  }
3523 
3524  while (scanner_isspace(*nextp))
3525  nextp++; /* skip trailing whitespace */
3526 
3527  if (*nextp == separator)
3528  {
3529  nextp++;
3530  while (scanner_isspace(*nextp))
3531  nextp++; /* skip leading whitespace for next */
3532  /* we expect another name, so done remains false */
3533  }
3534  else if (*nextp == '\0')
3535  done = true;
3536  else
3537  return false; /* invalid syntax */
3538 
3539  /* Now safe to overwrite separator with a null */
3540  *endp = '\0';
3541 
3542  /* Truncate name if it's overlength */
3543  truncate_identifier(curname, strlen(curname), false);
3544 
3545  /*
3546  * Finished isolating current name --- add it to list
3547  */
3548  *namelist = lappend(*namelist, curname);
3549 
3550  /* Loop back if we didn't reach end of string */
3551  } while (!done);
3552 
3553  return true;
3554 }
3555 
3556 
3557 /*
3558  * SplitDirectoriesString --- parse a string containing file/directory names
3559  *
3560  * This works fine on file names too; the function name is historical.
3561  *
3562  * This is similar to SplitIdentifierString, except that the parsing
3563  * rules are meant to handle pathnames instead of identifiers: there is
3564  * no downcasing, embedded spaces are allowed, the max length is MAXPGPATH-1,
3565  * and we apply canonicalize_path() to each extracted string. Because of the
3566  * last, the returned strings are separately palloc'd rather than being
3567  * pointers into rawstring --- but we still scribble on rawstring.
3568  *
3569  * Inputs:
3570  * rawstring: the input string; must be modifiable!
3571  * separator: the separator punctuation expected between directories
3572  * (typically ',' or ';'). Whitespace may also appear around
3573  * directories.
3574  * Outputs:
3575  * namelist: filled with a palloc'd list of directory names.
3576  * Caller should list_free_deep() this even on error return.
3577  *
3578  * Returns true if okay, false if there is a syntax error in the string.
3579  *
3580  * Note that an empty string is considered okay here.
3581  */
3582 bool
3583 SplitDirectoriesString(char *rawstring, char separator,
3584  List **namelist)
3585 {
3586  char *nextp = rawstring;
3587  bool done = false;
3588 
3589  *namelist = NIL;
3590 
3591  while (scanner_isspace(*nextp))
3592  nextp++; /* skip leading whitespace */
3593 
3594  if (*nextp == '\0')
3595  return true; /* allow empty string */
3596 
3597  /* At the top of the loop, we are at start of a new directory. */
3598  do
3599  {
3600  char *curname;
3601  char *endp;
3602 
3603  if (*nextp == '"')
3604  {
3605  /* Quoted name --- collapse quote-quote pairs */
3606  curname = nextp + 1;
3607  for (;;)
3608  {
3609  endp = strchr(nextp + 1, '"');
3610  if (endp == NULL)
3611  return false; /* mismatched quotes */
3612  if (endp[1] != '"')
3613  break; /* found end of quoted name */
3614  /* Collapse adjacent quotes into one quote, and look again */
3615  memmove(endp, endp + 1, strlen(endp));
3616  nextp = endp;
3617  }
3618  /* endp now points at the terminating quote */
3619  nextp = endp + 1;
3620  }
3621  else
3622  {
3623  /* Unquoted name --- extends to separator or end of string */
3624  curname = endp = nextp;
3625  while (*nextp && *nextp != separator)
3626  {
3627  /* trailing whitespace should not be included in name */
3628  if (!scanner_isspace(*nextp))
3629  endp = nextp + 1;
3630  nextp++;
3631  }
3632  if (curname == endp)
3633  return false; /* empty unquoted name not allowed */
3634  }
3635 
3636  while (scanner_isspace(*nextp))
3637  nextp++; /* skip trailing whitespace */
3638 
3639  if (*nextp == separator)
3640  {
3641  nextp++;
3642  while (scanner_isspace(*nextp))
3643  nextp++; /* skip leading whitespace for next */
3644  /* we expect another name, so done remains false */
3645  }
3646  else if (*nextp == '\0')
3647  done = true;
3648  else
3649  return false; /* invalid syntax */
3650 
3651  /* Now safe to overwrite separator with a null */
3652  *endp = '\0';
3653 
3654  /* Truncate path if it's overlength */
3655  if (strlen(curname) >= MAXPGPATH)
3656  curname[MAXPGPATH - 1] = '\0';
3657 
3658  /*
3659  * Finished isolating current name --- add it to list
3660  */
3661  curname = pstrdup(curname);
3662  canonicalize_path(curname);
3663  *namelist = lappend(*namelist, curname);
3664 
3665  /* Loop back if we didn't reach end of string */
3666  } while (!done);
3667 
3668  return true;
3669 }
3670 
3671 
3672 /*
3673  * SplitGUCList --- parse a string containing identifiers or file names
3674  *
3675  * This is used to split the value of a GUC_LIST_QUOTE GUC variable, without
3676  * presuming whether the elements will be taken as identifiers or file names.
3677  * We assume the input has already been through flatten_set_variable_args(),
3678  * so that we need never downcase (if appropriate, that was done already).
3679  * Nor do we ever truncate, since we don't know the correct max length.
3680  * We disallow embedded whitespace for simplicity (it shouldn't matter,
3681  * because any embedded whitespace should have led to double-quoting).
3682  * Otherwise the API is identical to SplitIdentifierString.
3683  *
3684  * XXX it's annoying to have so many copies of this string-splitting logic.
3685  * However, it's not clear that having one function with a bunch of option
3686  * flags would be much better.
3687  *
3688  * XXX there is a version of this function in src/bin/pg_dump/dumputils.c.
3689  * Be sure to update that if you have to change this.
3690  *
3691  * Inputs:
3692  * rawstring: the input string; must be overwritable! On return, it's
3693  * been modified to contain the separated identifiers.
3694  * separator: the separator punctuation expected between identifiers
3695  * (typically '.' or ','). Whitespace may also appear around
3696  * identifiers.
3697  * Outputs:
3698  * namelist: filled with a palloc'd list of pointers to identifiers within
3699  * rawstring. Caller should list_free() this even on error return.
3700  *
3701  * Returns true if okay, false if there is a syntax error in the string.
3702  */
3703 bool
3704 SplitGUCList(char *rawstring, char separator,
3705  List **namelist)
3706 {
3707  char *nextp = rawstring;
3708  bool done = false;
3709 
3710  *namelist = NIL;
3711 
3712  while (scanner_isspace(*nextp))
3713  nextp++; /* skip leading whitespace */
3714 
3715  if (*nextp == '\0')
3716  return true; /* allow empty string */
3717 
3718  /* At the top of the loop, we are at start of a new identifier. */
3719  do
3720  {
3721  char *curname;
3722  char *endp;
3723 
3724  if (*nextp == '"')
3725  {
3726  /* Quoted name --- collapse quote-quote pairs */
3727  curname = nextp + 1;
3728  for (;;)
3729  {
3730  endp = strchr(nextp + 1, '"');
3731  if (endp == NULL)
3732  return false; /* mismatched quotes */
3733  if (endp[1] != '"')
3734  break; /* found end of quoted name */
3735  /* Collapse adjacent quotes into one quote, and look again */
3736  memmove(endp, endp + 1, strlen(endp));
3737  nextp = endp;
3738  }
3739  /* endp now points at the terminating quote */
3740  nextp = endp + 1;
3741  }
3742  else
3743  {
3744  /* Unquoted name --- extends to separator or whitespace */
3745  curname = nextp;
3746  while (*nextp && *nextp != separator &&
3747  !scanner_isspace(*nextp))
3748  nextp++;
3749  endp = nextp;
3750  if (curname == nextp)
3751  return false; /* empty unquoted name not allowed */
3752  }
3753 
3754  while (scanner_isspace(*nextp))
3755  nextp++; /* skip trailing whitespace */
3756 
3757  if (*nextp == separator)
3758  {
3759  nextp++;
3760  while (scanner_isspace(*nextp))
3761  nextp++; /* skip leading whitespace for next */
3762  /* we expect another name, so done remains false */
3763  }
3764  else if (*nextp == '\0')
3765  done = true;
3766  else
3767  return false; /* invalid syntax */
3768 
3769  /* Now safe to overwrite separator with a null */
3770  *endp = '\0';
3771 
3772  /*
3773  * Finished isolating current name --- add it to list
3774  */
3775  *namelist = lappend(*namelist, curname);
3776 
3777  /* Loop back if we didn't reach end of string */
3778  } while (!done);
3779 
3780  return true;
3781 }
3782 
3783 
3784 /*****************************************************************************
3785  * Comparison Functions used for bytea
3786  *
3787  * Note: btree indexes need these routines not to leak memory; therefore,
3788  * be careful to free working copies of toasted datums. Most places don't
3789  * need to be so careful.
3790  *****************************************************************************/
3791 
3792 Datum
3794 {
3795  Datum arg1 = PG_GETARG_DATUM(0);
3796  Datum arg2 = PG_GETARG_DATUM(1);
3797  bool result;
3798  Size len1,
3799  len2;
3800 
3801  /*
3802  * We can use a fast path for unequal lengths, which might save us from
3803  * having to detoast one or both values.
3804  */
3805  len1 = toast_raw_datum_size(arg1);
3806  len2 = toast_raw_datum_size(arg2);
3807  if (len1 != len2)
3808  result = false;
3809  else
3810  {
3811  bytea *barg1 = DatumGetByteaPP(arg1);
3812  bytea *barg2 = DatumGetByteaPP(arg2);
3813 
3814  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3815  len1 - VARHDRSZ) == 0);
3816 
3817  PG_FREE_IF_COPY(barg1, 0);
3818  PG_FREE_IF_COPY(barg2, 1);
3819  }
3820 
3821  PG_RETURN_BOOL(result);
3822 }
3823 
3824 Datum
3826 {
3827  Datum arg1 = PG_GETARG_DATUM(0);
3828  Datum arg2 = PG_GETARG_DATUM(1);
3829  bool result;
3830  Size len1,
3831  len2;
3832 
3833  /*
3834  * We can use a fast path for unequal lengths, which might save us from
3835  * having to detoast one or both values.
3836  */
3837  len1 = toast_raw_datum_size(arg1);
3838  len2 = toast_raw_datum_size(arg2);
3839  if (len1 != len2)
3840  result = true;
3841  else
3842  {
3843  bytea *barg1 = DatumGetByteaPP(arg1);
3844  bytea *barg2 = DatumGetByteaPP(arg2);
3845 
3846  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3847  len1 - VARHDRSZ) != 0);
3848 
3849  PG_FREE_IF_COPY(barg1, 0);
3850  PG_FREE_IF_COPY(barg2, 1);
3851  }
3852 
3853  PG_RETURN_BOOL(result);
3854 }
3855 
3856 Datum
3858 {
3859  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3860  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3861  int len1,
3862  len2;
3863  int cmp;
3864 
3865  len1 = VARSIZE_ANY_EXHDR(arg1);
3866  len2 = VARSIZE_ANY_EXHDR(arg2);
3867 
3868  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3869 
3870  PG_FREE_IF_COPY(arg1, 0);
3871  PG_FREE_IF_COPY(arg2, 1);
3872 
3873  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
3874 }
3875 
3876 Datum
3878 {
3879  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3880  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3881  int len1,
3882  len2;
3883  int cmp;
3884 
3885  len1 = VARSIZE_ANY_EXHDR(arg1);
3886  len2 = VARSIZE_ANY_EXHDR(arg2);
3887 
3888  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3889 
3890  PG_FREE_IF_COPY(arg1, 0);
3891  PG_FREE_IF_COPY(arg2, 1);
3892 
3893  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
3894 }
3895 
3896 Datum
3898 {
3899  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3900  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3901  int len1,
3902  len2;
3903  int cmp;
3904 
3905  len1 = VARSIZE_ANY_EXHDR(arg1);
3906  len2 = VARSIZE_ANY_EXHDR(arg2);
3907 
3908  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3909 
3910  PG_FREE_IF_COPY(arg1, 0);
3911  PG_FREE_IF_COPY(arg2, 1);
3912 
3913  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
3914 }
3915 
3916 Datum
3918 {
3919  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3920  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3921  int len1,
3922  len2;
3923  int cmp;
3924 
3925  len1 = VARSIZE_ANY_EXHDR(arg1);
3926  len2 = VARSIZE_ANY_EXHDR(arg2);
3927 
3928  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3929 
3930  PG_FREE_IF_COPY(arg1, 0);
3931  PG_FREE_IF_COPY(arg2, 1);
3932 
3933  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
3934 }
3935 
3936 Datum
3938 {
3939  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3940  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3941  int len1,
3942  len2;
3943  int cmp;
3944 
3945  len1 = VARSIZE_ANY_EXHDR(arg1);
3946  len2 = VARSIZE_ANY_EXHDR(arg2);
3947 
3948  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3949  if ((cmp == 0) && (len1 != len2))
3950  cmp = (len1 < len2) ? -1 : 1;
3951 
3952  PG_FREE_IF_COPY(arg1, 0);
3953  PG_FREE_IF_COPY(arg2, 1);
3954 
3956 }
3957 
3958 Datum
3960 {
3962  MemoryContext oldcontext;
3963 
3964  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
3965 
3966  /* Use generic string SortSupport, forcing "C" collation */
3967  varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
3968 
3969  MemoryContextSwitchTo(oldcontext);
3970 
3971  PG_RETURN_VOID();
3972 }
3973 
3974 /*
3975  * appendStringInfoText
3976  *
3977  * Append a text to str.
3978  * Like appendStringInfoString(str, text_to_cstring(t)) but faster.
3979  */
3980 static void
3982 {
3984 }
3985 
3986 /*
3987  * replace_text
3988  * replace all occurrences of 'old_sub_str' in 'orig_str'
3989  * with 'new_sub_str' to form 'new_str'
3990  *
3991  * returns 'orig_str' if 'old_sub_str' == '' or 'orig_str' == ''
3992  * otherwise returns 'new_str'
3993  */
3994 Datum
3996 {
3997  text *src_text = PG_GETARG_TEXT_PP(0);
3998  text *from_sub_text = PG_GETARG_TEXT_PP(1);
3999  text *to_sub_text = PG_GETARG_TEXT_PP(2);
4000  int src_text_len;
4001  int from_sub_text_len;
4003  text *ret_text;
4004  int chunk_len;
4005  char *curr_ptr;
4006  char *start_ptr;
4008  bool found;
4009 
4010  src_text_len = VARSIZE_ANY_EXHDR(src_text);
4011  from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4012 
4013  /* Return unmodified source string if empty source or pattern */
4014  if (src_text_len < 1 || from_sub_text_len < 1)
4015  {
4016  PG_RETURN_TEXT_P(src_text);
4017  }
4018 
4019  text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4020 
4021  found = text_position_next(&state);
4022 
4023  /* When the from_sub_text is not found, there is nothing to do. */
4024  if (!found)
4025  {
4027  PG_RETURN_TEXT_P(src_text);
4028  }
4029  curr_ptr = text_position_get_match_ptr(&state);
4030  start_ptr = VARDATA_ANY(src_text);
4031 
4032  initStringInfo(&str);
4033 
4034  do
4035  {
4037 
4038  /* copy the data skipped over by last text_position_next() */
4039  chunk_len = curr_ptr - start_ptr;
4040  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4041 
4042  appendStringInfoText(&str, to_sub_text);
4043 
4044  start_ptr = curr_ptr + from_sub_text_len;
4045 
4046  found = text_position_next(&state);
4047  if (found)
4048  curr_ptr = text_position_get_match_ptr(&state);
4049  }
4050  while (found);
4051 
4052  /* copy trailing data */
4053  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4054  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4055 
4057 
4058  ret_text = cstring_to_text_with_len(str.data, str.len);
4059  pfree(str.data);
4060 
4061  PG_RETURN_TEXT_P(ret_text);
4062 }
4063 
4064 /*
4065  * check_replace_text_has_escape
4066  *
4067  * Returns 0 if text contains no backslashes that need processing.
4068  * Returns 1 if text contains backslashes, but not regexp submatch specifiers.
4069  * Returns 2 if text contains regexp submatch specifiers (\1 .. \9).
4070  */
4071 static int
4073 {
4074  int result = 0;
4075  const char *p = VARDATA_ANY(replace_text);
4076  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4077 
4078  while (p < p_end)
4079  {
4080  /* Find next escape char, if any. */
4081  p = memchr(p, '\\', p_end - p);
4082  if (p == NULL)
4083  break;
4084  p++;
4085  /* Note: a backslash at the end doesn't require extra processing. */
4086  if (p < p_end)
4087  {
4088  if (*p >= '1' && *p <= '9')
4089  return 2; /* Found a submatch specifier, so done */
4090  result = 1; /* Found some other sequence, keep looking */
4091  p++;
4092  }
4093  }
4094  return result;
4095 }
4096 
4097 /*
4098  * appendStringInfoRegexpSubstr
4099  *
4100  * Append replace_text to str, substituting regexp back references for
4101  * \n escapes. start_ptr is the start of the match in the source string,
4102  * at logical character position data_pos.
4103  */
4104 static void
4106  regmatch_t *pmatch,
4107  char *start_ptr, int data_pos)
4108 {
4109  const char *p = VARDATA_ANY(replace_text);
4110  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4111 
4112  while (p < p_end)
4113  {
4114  const char *chunk_start = p;
4115  int so;
4116  int eo;
4117 
4118  /* Find next escape char, if any. */
4119  p = memchr(p, '\\', p_end - p);
4120  if (p == NULL)
4121  p = p_end;
4122 
4123  /* Copy the text we just scanned over, if any. */
4124  if (p > chunk_start)
4125  appendBinaryStringInfo(str, chunk_start, p - chunk_start);
4126 
4127  /* Done if at end of string, else advance over escape char. */
4128  if (p >= p_end)
4129  break;
4130  p++;
4131 
4132  if (p >= p_end)
4133  {
4134  /* Escape at very end of input. Treat same as unexpected char */
4135  appendStringInfoChar(str, '\\');
4136  break;
4137  }
4138 
4139  if (*p >= '1' && *p <= '9')
4140  {
4141  /* Use the back reference of regexp. */
4142  int idx = *p - '0';
4143 
4144  so = pmatch[idx].rm_so;
4145  eo = pmatch[idx].rm_eo;
4146  p++;
4147  }
4148  else if (*p == '&')
4149  {
4150  /* Use the entire matched string. */
4151  so = pmatch[0].rm_so;
4152  eo = pmatch[0].rm_eo;
4153  p++;
4154  }
4155  else if (*p == '\\')
4156  {
4157  /* \\ means transfer one \ to output. */
4158  appendStringInfoChar(str, '\\');
4159  p++;
4160  continue;
4161  }
4162  else
4163  {
4164  /*
4165  * If escape char is not followed by any expected char, just treat
4166  * it as ordinary data to copy. (XXX would it be better to throw
4167  * an error?)
4168  */
4169  appendStringInfoChar(str, '\\');
4170  continue;
4171  }
4172 
4173  if (so >= 0 && eo >= 0)
4174  {
4175  /*
4176  * Copy the text that is back reference of regexp. Note so and eo
4177  * are counted in characters not bytes.
4178  */
4179  char *chunk_start;
4180  int chunk_len;
4181 
4182  Assert(so >= data_pos);
4183  chunk_start = start_ptr;
4184  chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
4185  chunk_len = charlen_to_bytelen(chunk_start, eo - so);
4186  appendBinaryStringInfo(str, chunk_start, chunk_len);
4187  }
4188  }
4189 }
4190 
4191 /*
4192  * replace_text_regexp
4193  *
4194  * replace substring(s) in src_text that match pattern with replace_text.
4195  * The replace_text can contain backslash markers to substitute
4196  * (parts of) the matched text.
4197  *
4198  * cflags: regexp compile flags.
4199  * collation: collation to use.
4200  * search_start: the character (not byte) offset in src_text at which to
4201  * begin searching.
4202  * n: if 0, replace all matches; if > 0, replace only the N'th match.
4203  */
4204 text *
4205 replace_text_regexp(text *src_text, text *pattern_text,
4206  text *replace_text,
4207  int cflags, Oid collation,
4208  int search_start, int n)
4209 {
4210  text *ret_text;
4211  regex_t *re;
4212  int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4213  int nmatches = 0;
4215  regmatch_t pmatch[10]; /* main match, plus \1 to \9 */
4216  int nmatch = lengthof(pmatch);
4217  pg_wchar *data;
4218  size_t data_len;
4219  int data_pos;
4220  char *start_ptr;
4221  int escape_status;
4222 
4223  initStringInfo(&buf);
4224 
4225  /* Convert data string to wide characters. */
4226  data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4227  data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4228 
4229  /* Check whether replace_text has escapes, especially regexp submatches. */
4231 
4232  /* If no regexp submatches, we can use REG_NOSUB. */
4233  if (escape_status < 2)
4234  {
4235  cflags |= REG_NOSUB;
4236  /* Also tell pg_regexec we only want the whole-match location. */
4237  nmatch = 1;
4238  }
4239 
4240  /* Prepare the regexp. */
4241  re = RE_compile_and_cache(pattern_text, cflags, collation);
4242 
4243  /* start_ptr points to the data_pos'th character of src_text */
4244  start_ptr = (char *) VARDATA_ANY(src_text);
4245  data_pos = 0;
4246 
4247  while (search_start <= data_len)
4248  {
4249  int regexec_result;
4250 
4252 
4253  regexec_result = pg_regexec(re,
4254  data,
4255  data_len,
4256  search_start,
4257  NULL, /* no details */
4258  nmatch,
4259  pmatch,
4260  0);
4261 
4262  if (regexec_result == REG_NOMATCH)
4263  break;
4264 
4265  if (regexec_result != REG_OKAY)
4266  {
4267  char errMsg[100];
4268 
4269  pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4270  ereport(ERROR,
4271  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4272  errmsg("regular expression failed: %s", errMsg)));
4273  }
4274 
4275  /*
4276  * Count matches, and decide whether to replace this match.
4277  */
4278  nmatches++;
4279  if (n > 0 && nmatches != n)
4280  {
4281  /*
4282  * No, so advance search_start, but not start_ptr/data_pos. (Thus,
4283  * we treat the matched text as if it weren't matched, and copy it
4284  * to the output later.)
4285  */
4286  search_start = pmatch[0].rm_eo;
4287  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4288  search_start++;
4289  continue;
4290  }
4291 
4292  /*
4293  * Copy the text to the left of the match position. Note we are given
4294  * character not byte indexes.
4295  */
4296  if (pmatch[0].rm_so - data_pos > 0)
4297  {
4298  int chunk_len;
4299 
4300  chunk_len = charlen_to_bytelen(start_ptr,
4301  pmatch[0].rm_so - data_pos);
4302  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4303 
4304  /*
4305  * Advance start_ptr over that text, to avoid multiple rescans of
4306  * it if the replace_text contains multiple back-references.
4307  */
4308  start_ptr += chunk_len;
4309  data_pos = pmatch[0].rm_so;
4310  }
4311 
4312  /*
4313  * Copy the replace_text, processing escapes if any are present.
4314  */
4315  if (escape_status > 0)
4317  start_ptr, data_pos);
4318  else
4320 
4321  /* Advance start_ptr and data_pos over the matched text. */
4322  start_ptr += charlen_to_bytelen(start_ptr,
4323  pmatch[0].rm_eo - data_pos);
4324  data_pos = pmatch[0].rm_eo;
4325 
4326  /*
4327  * If we only want to replace one occurrence, we're done.
4328  */
4329  if (n > 0)
4330  break;
4331 
4332  /*
4333  * Advance search position. Normally we start the next search at the
4334  * end of the previous match; but if the match was of zero length, we
4335  * have to advance by one character, or we'd just find the same match
4336  * again.
4337  */
4338  search_start = data_pos;
4339  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4340  search_start++;
4341  }
4342 
4343  /*
4344  * Copy the text to the right of the last match.
4345  */
4346  if (data_pos < data_len)
4347  {
4348  int chunk_len;
4349 
4350  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4351  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4352  }
4353 
4354  ret_text = cstring_to_text_with_len(buf.data, buf.len);
4355  pfree(buf.data);
4356  pfree(data);
4357 
4358  return ret_text;
4359 }
4360 
4361 /*
4362  * split_part
4363  * parse input string based on provided field separator
4364  * return N'th item (1 based, negative counts from end)
4365  */
4366 Datum
4368 {
4369  text *inputstring = PG_GETARG_TEXT_PP(0);
4370  text *fldsep = PG_GETARG_TEXT_PP(1);
4371  int fldnum = PG_GETARG_INT32(2);
4372  int inputstring_len;
4373  int fldsep_len;
4375  char *start_ptr;
4376  char *end_ptr;
4377  text *result_text;
4378  bool found;
4379 
4380  /* field number is 1 based */
4381  if (fldnum == 0)
4382  ereport(ERROR,
4383  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4384  errmsg("field position must not be zero")));
4385 
4386  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4387  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4388 
4389  /* return empty string for empty input string */
4390  if (inputstring_len < 1)
4392 
4393  /* handle empty field separator */
4394  if (fldsep_len < 1)
4395  {
4396  /* if first or last field, return input string, else empty string */
4397  if (fldnum == 1 || fldnum == -1)
4398  PG_RETURN_TEXT_P(inputstring);
4399  else
4401  }
4402 
4403  /* find the first field separator */
4404  text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4405 
4406  found = text_position_next(&state);
4407 
4408  /* special case if fldsep not found at all */
4409  if (!found)
4410  {
4412  /* if first or last field, return input string, else empty string */
4413  if (fldnum == 1 || fldnum == -1)
4414  PG_RETURN_TEXT_P(inputstring);
4415  else
4417  }
4418 
4419  /*
4420  * take care of a negative field number (i.e. count from the right) by
4421  * converting to a positive field number; we need total number of fields
4422  */
4423  if (fldnum < 0)
4424  {
4425  /* we found a fldsep, so there are at least two fields */
4426  int numfields = 2;
4427 
4428  while (text_position_next(&state))
4429  numfields++;
4430 
4431  /* special case of last field does not require an extra pass */
4432  if (fldnum == -1)
4433  {
4434  start_ptr = text_position_get_match_ptr(&state) + fldsep_len;
4435  end_ptr = VARDATA_ANY(inputstring) + inputstring_len;
4438  end_ptr - start_ptr));
4439  }
4440 
4441  /* else, convert fldnum to positive notation */
4442  fldnum += numfields + 1;
4443 
4444  /* if nonexistent field, return empty string */
4445  if (fldnum <= 0)
4446  {
4449  }
4450 
4451  /* reset to pointing at first match, but now with positive fldnum */
4453  found = text_position_next(&state);
4454  Assert(found);
4455  }
4456 
4457  /* identify bounds of first field */
4458  start_ptr = VARDATA_ANY(inputstring);
4459  end_ptr = text_position_get_match_ptr(&state);
4460 
4461  while (found && --fldnum > 0)
4462  {
4463  /* identify bounds of next field */
4464  start_ptr = end_ptr + fldsep_len;
4465  found = text_position_next(&state);
4466  if (found)
4467  end_ptr = text_position_get_match_ptr(&state);
4468  }
4469 
4471 
4472  if (fldnum > 0)
4473  {
4474  /* N'th field separator not found */
4475  /* if last field requested, return it, else empty string */
4476  if (fldnum == 1)
4477  {
4478  int last_len = start_ptr - VARDATA_ANY(inputstring);
4479 
4480  result_text = cstring_to_text_with_len(start_ptr,
4481  inputstring_len - last_len);
4482  }
4483  else
4484  result_text = cstring_to_text("");
4485  }
4486  else
4487  {
4488  /* non-last field requested */
4489  result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4490  }
4491 
4492  PG_RETURN_TEXT_P(result_text);
4493 }
4494 
4495 /*
4496  * Convenience function to return true when two text params are equal.
4497  */
4498 static bool
4500 {
4502  collid,
4503  PointerGetDatum(txt1),
4504  PointerGetDatum(txt2)));
4505 }
4506 
4507 /*
4508  * text_to_array
4509  * parse input string and return text array of elements,
4510  * based on provided field separator
4511  */
4512 Datum
4514 {
4515  SplitTextOutputData tstate;
4516 
4517  /* For array output, tstate should start as all zeroes */
4518  memset(&tstate, 0, sizeof(tstate));
4519 
4520  if (!split_text(fcinfo, &tstate))
4521  PG_RETURN_NULL();
4522 
4523  if (tstate.astate == NULL)
4525 
4528 }
4529 
4530 /*
4531  * text_to_array_null
4532  * parse input string and return text array of elements,
4533  * based on provided field separator and null string
4534  *
4535  * This is a separate entry point only to prevent the regression tests from
4536  * complaining about different argument sets for the same internal function.
4537  */
4538 Datum
4540 {
4541  return text_to_array(fcinfo);
4542 }
4543 
4544 /*
4545  * text_to_table
4546  * parse input string and return table of elements,
4547  * based on provided field separator
4548  */
4549 Datum
4551 {
4552  ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
4553  SplitTextOutputData tstate;
4554 
4555  tstate.astate = NULL;
4557  tstate.tupstore = rsi->setResult;
4558  tstate.tupdesc = rsi->setDesc;
4559 
4560  (void) split_text(fcinfo, &tstate);
4561 
4562  return (Datum) 0;
4563 }
4564 
4565 /*
4566  * text_to_table_null
4567  * parse input string and return table of elements,
4568  * based on provided field separator and null string
4569  *
4570  * This is a separate entry point only to prevent the regression tests from
4571  * complaining about different argument sets for the same internal function.
4572  */
4573 Datum
4575 {
4576  return text_to_table(fcinfo);
4577 }
4578 
4579 /*
4580  * Common code for text_to_array, text_to_array_null, text_to_table
4581  * and text_to_table_null functions.
4582  *
4583  * These are not strict so we have to test for null inputs explicitly.
4584  * Returns false if result is to be null, else returns true.
4585  *
4586  * Note that if the result is valid but empty (zero elements), we return
4587  * without changing *tstate --- caller must handle that case, too.
4588  */
4589 static bool
4591 {
4592  text *inputstring;
4593  text *fldsep;
4594  text *null_string;
4595  Oid collation = PG_GET_COLLATION();
4596  int inputstring_len;
4597  int fldsep_len;
4598  char *start_ptr;
4599  text *result_text;
4600 
4601  /* when input string is NULL, then result is NULL too */
4602  if (PG_ARGISNULL(0))
4603  return false;
4604 
4605  inputstring = PG_GETARG_TEXT_PP(0);
4606 
4607  /* fldsep can be NULL */
4608  if (!PG_ARGISNULL(1))
4609  fldsep = PG_GETARG_TEXT_PP(1);
4610  else
4611  fldsep = NULL;
4612 
4613  /* null_string can be NULL or omitted */
4614  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
4615  null_string = PG_GETARG_TEXT_PP(2);
4616  else
4617  null_string = NULL;
4618 
4619  if (fldsep != NULL)
4620  {
4621  /*
4622  * Normal case with non-null fldsep. Use the text_position machinery
4623  * to search for occurrences of fldsep.
4624  */
4626 
4627  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4628  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4629 
4630  /* return empty set for empty input string */
4631  if (inputstring_len < 1)
4632  return true;
4633 
4634  /* empty field separator: return input string as a one-element set */
4635  if (fldsep_len < 1)
4636  {
4637  split_text_accum_result(tstate, inputstring,
4638  null_string, collation);
4639  return true;
4640  }
4641 
4642  text_position_setup(inputstring, fldsep, collation, &state);
4643 
4644  start_ptr = VARDATA_ANY(inputstring);
4645 
4646  for (;;)
4647  {
4648  bool found;
4649  char *end_ptr;
4650  int chunk_len;
4651 
4653 
4654  found = text_position_next(&state);
4655  if (!found)
4656  {
4657  /* fetch last field */
4658  chunk_len = ((char *) inputstring + VARSIZE_ANY(inputstring)) - start_ptr;
4659  end_ptr = NULL; /* not used, but some compilers complain */
4660  }
4661  else
4662  {
4663  /* fetch non-last field */
4664  end_ptr = text_position_get_match_ptr(&state);
4665  chunk_len = end_ptr - start_ptr;
4666  }
4667 
4668  /* build a temp text datum to pass to split_text_accum_result */
4669  result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4670 
4671  /* stash away this field */
4672  split_text_accum_result(tstate, result_text,
4673  null_string, collation);
4674 
4675  pfree(result_text);
4676 
4677  if (!found)
4678  break;
4679 
4680  start_ptr = end_ptr + fldsep_len;
4681  }
4682 
4684  }
4685  else
4686  {
4687  /*
4688  * When fldsep is NULL, each character in the input string becomes a
4689  * separate element in the result set. The separator is effectively
4690  * the space between characters.
4691  */
4692  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4693 
4694  start_ptr = VARDATA_ANY(inputstring);
4695 
4696  while (inputstring_len > 0)
4697  {
4698  int chunk_len = pg_mblen(start_ptr);
4699 
4701 
4702  /* build a temp text datum to pass to split_text_accum_result */
4703  result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4704 
4705  /* stash away this field */
4706  split_text_accum_result(tstate, result_text,
4707  null_string, collation);
4708 
4709  pfree(result_text);
4710 
4711  start_ptr += chunk_len;
4712  inputstring_len -= chunk_len;
4713  }
4714  }
4715 
4716  return true;
4717 }
4718 
4719 /*
4720  * Add text item to result set (table or array).
4721  *
4722  * This is also responsible for checking to see if the item matches
4723  * the null_string, in which case we should emit NULL instead.
4724  */
4725 static void
4727  text *field_value,
4728  text *null_string,
4729  Oid collation)
4730 {
4731  bool is_null = false;
4732 
4733  if (null_string && text_isequal(field_value, null_string, collation))
4734  is_null = true;
4735 
4736  if (tstate->tupstore)
4737  {
4738  Datum values[1];
4739  bool nulls[1];
4740 
4741  values[0] = PointerGetDatum(field_value);
4742  nulls[0] = is_null;
4743 
4745  tstate->tupdesc,
4746  values,
4747  nulls);
4748  }
4749  else
4750  {
4751  tstate->astate = accumArrayResult(tstate->astate,
4752  PointerGetDatum(field_value),
4753  is_null,
4754  TEXTOID,
4756  }
4757 }
4758 
4759 /*
4760  * array_to_text
4761  * concatenate Cstring representation of input array elements
4762  * using provided field separator
4763  */
4764 Datum
4766 {
4768  char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4769 
4770  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4771 }
4772 
4773 /*
4774  * array_to_text_null
4775  * concatenate Cstring representation of input array elements
4776  * using provided field separator and null string
4777  *
4778  * This version is not strict so we have to test for null inputs explicitly.
4779  */
4780 Datum
4782 {
4783  ArrayType *v;
4784  char *fldsep;
4785  char *null_string;
4786 
4787  /* returns NULL when first or second parameter is NULL */
4788  if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4789  PG_RETURN_NULL();
4790 
4791  v = PG_GETARG_ARRAYTYPE_P(0);
4792  fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4793 
4794  /* NULL null string is passed through as a null pointer */
4795  if (!PG_ARGISNULL(2))
4796  null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
4797  else
4798  null_string = NULL;
4799 
4800  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
4801 }
4802 
4803 /*
4804  * common code for array_to_text and array_to_text_null functions
4805  */
4806 static text *
4808  const char *fldsep, const char *null_string)
4809 {
4810  text *result;
4811  int nitems,
4812  *dims,
4813  ndims;
4814  Oid element_type;
4815  int typlen;
4816  bool typbyval;
4817  char typalign;
4819  bool printed = false;
4820  char *p;
4821  bits8 *bitmap;
4822  int bitmask;
4823  int i;
4824  ArrayMetaState *my_extra;
4825 
4826  ndims = ARR_NDIM(v);
4827  dims = ARR_DIMS(v);
4828  nitems = ArrayGetNItems(ndims, dims);
4829 
4830  /* if there are no elements, return an empty string */
4831  if (nitems == 0)
4832  return cstring_to_text_with_len("", 0);
4833 
4834  element_type = ARR_ELEMTYPE(v);
4835  initStringInfo(&buf);
4836 
4837  /*
4838  * We arrange to look up info about element type, including its output
4839  * conversion proc, only once per series of calls, assuming the element
4840  * type doesn't change underneath us.
4841  */
4842  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4843  if (my_extra == NULL)
4844  {
4845  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4846  sizeof(ArrayMetaState));
4847  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4848  my_extra->element_type = ~element_type;
4849  }
4850 
4851  if (my_extra->element_type != element_type)
4852  {
4853  /*
4854  * Get info about element type, including its output conversion proc
4855  */
4856  get_type_io_data(element_type, IOFunc_output,
4857  &my_extra->typlen, &my_extra->typbyval,
4858  &my_extra->typalign, &my_extra->typdelim,
4859  &my_extra->typioparam, &my_extra->typiofunc);
4860  fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
4861  fcinfo->flinfo->fn_mcxt);
4862  my_extra->element_type = element_type;
4863  }
4864  typlen = my_extra->typlen;
4865  typbyval = my_extra->typbyval;
4866  typalign = my_extra->typalign;
4867 
4868  p = ARR_DATA_PTR(v);
4869  bitmap = ARR_NULLBITMAP(v);
4870  bitmask = 1;
4871 
4872  for (i = 0; i < nitems; i++)
4873  {
4874  Datum itemvalue;
4875  char *value;
4876 
4877  /* Get source element, checking for NULL */
4878  if (bitmap && (*bitmap & bitmask) == 0)
4879  {
4880  /* if null_string is NULL, we just ignore null elements */
4881  if (null_string != NULL)
4882  {
4883  if (printed)
4884  appendStringInfo(&buf, "%s%s", fldsep, null_string);
4885  else
4886  appendStringInfoString(&buf, null_string);
4887  printed = true;
4888  }
4889  }
4890  else
4891  {
4892  itemvalue = fetch_att(p, typbyval, typlen);
4893 
4894  value = OutputFunctionCall(&my_extra->proc, itemvalue);
4895 
4896  if (printed)
4897  appendStringInfo(&buf, "%s%s", fldsep, value);
4898  else
4900  printed = true;
4901 
4902  p = att_addlength_pointer(p, typlen, p);
4903  p = (char *) att_align_nominal(p, typalign);
4904  }
4905 
4906  /* advance bitmap pointer if any */
4907  if (bitmap)
4908  {
4909  bitmask <<= 1;
4910  if (bitmask == 0x100)
4911  {
4912  bitmap++;
4913  bitmask = 1;
4914  }
4915  }
4916  }
4917 
4918  result = cstring_to_text_with_len(buf.data, buf.len);
4919  pfree(buf.data);
4920 
4921  return result;
4922 }
4923 
4924 /*
4925  * Workhorse for to_bin, to_oct, and to_hex. Note that base must be > 1 and <=
4926  * 16.
4927  */
4928 static inline text *
4929 convert_to_base(uint64 value, int base)
4930 {
4931  const char *digits = "0123456789abcdef";
4932 
4933  /* We size the buffer for to_bin's longest possible return value. */
4934  char buf[sizeof(uint64) * BITS_PER_BYTE];
4935  char *const end = buf + sizeof(buf);
4936  char *ptr = end;
4937 
4938  Assert(base > 1);
4939  Assert(base <= 16);
4940 
4941  do
4942  {
4943  *--ptr = digits[value % base];
4944  value /= base;
4945  } while (ptr > buf && value);
4946 
4947  return cstring_to_text_with_len(ptr, end - ptr);
4948 }
4949 
4950 /*
4951  * Convert an integer to a string containing a base-2 (binary) representation
4952  * of the number.
4953  */
4954 Datum
4956 {
4957  uint64 value = (uint32) PG_GETARG_INT32(0);
4958 
4960 }
4961 Datum
4963 {
4964  uint64 value = (uint64) PG_GETARG_INT64(0);
4965 
4967 }
4968 
4969 /*
4970  * Convert an integer to a string containing a base-8 (oct) representation of
4971  * the number.
4972  */
4973 Datum
4975 {
4976  uint64 value = (uint32) PG_GETARG_INT32(0);
4977 
4979 }
4980 Datum
4982 {
4983  uint64 value = (uint64) PG_GETARG_INT64(0);
4984 
4986 }
4987 
4988 /*
4989  * Convert an integer to a string containing a base-16 (hex) representation of
4990  * the number.
4991  */
4992 Datum
4994 {
4995  uint64 value = (uint32) PG_GETARG_INT32(0);
4996 
4998 }
4999 Datum
5001 {
5002  uint64 value = (uint64) PG_GETARG_INT64(0);
5003 
5005 }
5006 
5007 /*
5008  * Return the size of a datum, possibly compressed
5009  *
5010  * Works on any data type
5011  */
5012 Datum
5014 {
5016  int32 result;
5017  int typlen;
5018 
5019  /* On first call, get the input type's typlen, and save at *fn_extra */
5020  if (fcinfo->flinfo->fn_extra == NULL)
5021  {
5022  /* Lookup the datatype of the supplied argument */
5023  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5024 
5025  typlen = get_typlen(argtypeid);
5026  if (typlen == 0) /* should not happen */
5027  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5028 
5029  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5030  sizeof(int));
5031  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5032  }
5033  else
5034  typlen = *((int *) fcinfo->flinfo->fn_extra);
5035 
5036  if (typlen == -1)
5037  {
5038  /* varlena type, possibly toasted */
5039  result = toast_datum_size(value);
5040  }
5041  else if (typlen == -2)
5042  {
5043  /* cstring */
5044  result = strlen(DatumGetCString(value)) + 1;
5045  }
5046  else
5047  {
5048  /* ordinary fixed-width type */
5049  result = typlen;
5050  }
5051 
5052  PG_RETURN_INT32(result);
5053 }
5054 
5055 /*
5056  * Return the compression method stored in the compressed attribute. Return
5057  * NULL for non varlena type or uncompressed data.
5058  */
5059 Datum
5061 {
5062  int typlen;
5063  char *result;
5064  ToastCompressionId cmid;
5065 
5066  /* On first call, get the input type's typlen, and save at *fn_extra */
5067  if (fcinfo->flinfo->fn_extra == NULL)
5068  {
5069  /* Lookup the datatype of the supplied argument */
5070  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5071 
5072  typlen = get_typlen(argtypeid);
5073  if (typlen == 0) /* should not happen */
5074  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5075 
5076  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5077  sizeof(int));
5078  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5079  }
5080  else
5081  typlen = *((int *) fcinfo->flinfo->fn_extra);
5082 
5083  if (typlen != -1)
5084  PG_RETURN_NULL();
5085 
5086  /* get the compression method id stored in the compressed varlena */
5087  cmid = toast_get_compression_id((struct varlena *)
5089  if (cmid == TOAST_INVALID_COMPRESSION_ID)
5090  PG_RETURN_NULL();
5091 
5092  /* convert compression method id to compression method name */
5093  switch (cmid)
5094  {
5096  result = "pglz";
5097  break;
5099  result = "lz4";
5100  break;
5101  default:
5102  elog(ERROR, "invalid compression method id %d", cmid);
5103  }
5104 
5106 }
5107 
5108 /*
5109  * Return the chunk_id of the on-disk TOASTed value. Return NULL if the value
5110  * is un-TOASTed or not on-disk.
5111  */
5112 Datum
5114 {
5115  int typlen;
5116  struct varlena *attr;
5117  struct varatt_external toast_pointer;
5118 
5119  /* On first call, get the input type's typlen, and save at *fn_extra */
5120  if (fcinfo->flinfo->fn_extra == NULL)
5121  {
5122  /* Lookup the datatype of the supplied argument */
5123  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5124 
5125  typlen = get_typlen(argtypeid);
5126  if (typlen == 0) /* should not happen */
5127  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5128 
5129  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5130  sizeof(int));
5131  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5132  }
5133  else
5134  typlen = *((int *) fcinfo->flinfo->fn_extra);
5135 
5136  if (typlen != -1)
5137  PG_RETURN_NULL();
5138 
5139  attr = (struct varlena *) DatumGetPointer(PG_GETARG_DATUM(0));
5140 
5141  if (!VARATT_IS_EXTERNAL_ONDISK(attr))
5142  PG_RETURN_NULL();
5143 
5144  VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
5145 
5146  PG_RETURN_OID(toast_pointer.va_valueid);
5147 }
5148 
5149 /*
5150  * string_agg - Concatenates values and returns string.
5151  *
5152  * Syntax: string_agg(value text, delimiter text) RETURNS text
5153  *
5154  * Note: Any NULL values are ignored. The first-call delimiter isn't
5155  * actually used at all, and on subsequent calls the delimiter precedes
5156  * the associated value.
5157  */
5158 
5159 /* subroutine to initialize state */
5160 static StringInfo
5162 {
5163  StringInfo state;
5164  MemoryContext aggcontext;
5165  MemoryContext oldcontext;
5166 
5167  if (!AggCheckCallContext(fcinfo, &aggcontext))
5168  {
5169  /* cannot be called directly because of internal-type argument */
5170  elog(ERROR, "string_agg_transfn called in non-aggregate context");
5171  }
5172 
5173  /*
5174  * Create state in aggregate context. It'll stay there across subsequent
5175  * calls.
5176  */
5177  oldcontext = MemoryContextSwitchTo(aggcontext);
5178  state = makeStringInfo();
5179  MemoryContextSwitchTo(oldcontext);
5180 
5181  return state;
5182 }
5183 
5184 Datum
5186 {
5187  StringInfo state;
5188 
5189  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5190 
5191  /* Append the value unless null, preceding it with the delimiter. */
5192  if (!PG_ARGISNULL(1))
5193  {
5195  bool isfirst = false;
5196 
5197  /*
5198  * You might think we can just throw away the first delimiter, however
5199  * we must keep it as we may be a parallel worker doing partial
5200  * aggregation building a state to send to the main process. We need
5201  * to keep the delimiter of every aggregation so that the combine
5202  * function can properly join up the strings of two separately
5203  * partially aggregated results. The first delimiter is only stripped
5204  * off in the final function. To know how much to strip off the front
5205  * of the string, we store the length of the first delimiter in the
5206  * StringInfo's cursor field, which we don't otherwise need here.
5207  */
5208  if (state == NULL)
5209  {
5210  state = makeStringAggState(fcinfo);
5211  isfirst = true;
5212  }
5213 
5214  if (!PG_ARGISNULL(2))
5215  {
5216  text *delim = PG_GETARG_TEXT_PP(2);
5217 
5218  appendStringInfoText(state, delim);
5219  if (isfirst)
5220  state->cursor = VARSIZE_ANY_EXHDR(delim);
5221  }
5222 
5224  }
5225 
5226  /*
5227  * The transition type for string_agg() is declared to be "internal",
5228  * which is a pass-by-value type the same size as a pointer.
5229  */
5230  if (state)
5232  PG_RETURN_NULL();
5233 }
5234 
5235 /*
5236  * string_agg_combine
5237  * Aggregate combine function for string_agg(text) and string_agg(bytea)
5238  */
5239 Datum
5241 {
5242  StringInfo state1;
5243  StringInfo state2;
5244  MemoryContext agg_context;
5245 
5246  if (!AggCheckCallContext(fcinfo, &agg_context))
5247  elog(ERROR, "aggregate function called in non-aggregate context");
5248 
5249  state1 = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5250  state2 = PG_ARGISNULL(1) ? NULL : (StringInfo) PG_GETARG_POINTER(1);
5251 
5252  if (state2 == NULL)
5253  {
5254  /*
5255  * NULL state2 is easy, just return state1, which we know is already
5256  * in the agg_context
5257  */
5258  if (state1 == NULL)
5259  PG_RETURN_NULL();
5260  PG_RETURN_POINTER(state1);
5261  }
5262 
5263  if (state1 == NULL)
5264  {
5265  /* We must copy state2's data into the agg_context */
5266  MemoryContext old_context;
5267 
5268  old_context = MemoryContextSwitchTo(agg_context);
5269  state1 = makeStringAggState(fcinfo);
5270  appendBinaryStringInfo(state1, state2->data, state2->len);
5271  state1->cursor = state2->cursor;
5272  MemoryContextSwitchTo(old_context);
5273  }
5274  else if (state2->len > 0)
5275  {
5276  /* Combine ... state1->cursor does not change in this case */
5277  appendBinaryStringInfo(state1, state2->data, state2->len);
5278  }
5279 
5280  PG_RETURN_POINTER(state1);
5281 }
5282 
5283 /*
5284  * string_agg_serialize
5285  * Aggregate serialize function for string_agg(text) and string_agg(bytea)
5286  *
5287  * This is strict, so we need not handle NULL input
5288  */
5289 Datum
5291 {
5292  StringInfo state;
5294  bytea *result;
5295 
5296  /* cannot be called directly because of internal-type argument */
5297  Assert(AggCheckCallContext(fcinfo, NULL));
5298 
5300 
5301  pq_begintypsend(&buf);
5302 
5303  /* cursor */
5304  pq_sendint(&buf, state->cursor, 4);
5305 
5306  /* data */
5307  pq_sendbytes(&buf, state->data, state->len);
5308 
5309  result = pq_endtypsend(&buf);
5310 
5311  PG_RETURN_BYTEA_P(result);
5312 }
5313 
5314 /*
5315  * string_agg_deserialize
5316  * Aggregate deserial function for string_agg(text) and string_agg(bytea)
5317  *
5318  * This is strict, so we need not handle NULL input
5319  */
5320 Datum
5322 {
5323  bytea *sstate;
5324  StringInfo result;
5326  char *data;
5327  int datalen;
5328 
5329  /* cannot be called directly because of internal-type argument */
5330  Assert(AggCheckCallContext(fcinfo, NULL));
5331 
5332  sstate = PG_GETARG_BYTEA_PP(0);
5333 
5334  /*
5335  * Initialize a StringInfo so that we can "receive" it using the standard
5336  * recv-function infrastructure.
5337  */
5339  VARSIZE_ANY_EXHDR(sstate));
5340 
5341  result = makeStringAggState(fcinfo);
5342 
5343  /* cursor */
5344  result->cursor = pq_getmsgint(&buf, 4);
5345 
5346  /* data */
5347  datalen = VARSIZE_ANY_EXHDR(sstate) - 4;
5348  data = (char *) pq_getmsgbytes(&buf, datalen);
5349  appendBinaryStringInfo(result, data, datalen);
5350 
5351  pq_getmsgend(&buf);
5352 
5353  PG_RETURN_POINTER(result);
5354 }
5355 
5356 Datum
5358 {
5359  StringInfo state;
5360 
5361  /* cannot be called directly because of internal-type argument */
5362  Assert(AggCheckCallContext(fcinfo, NULL));
5363 
5364  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5365 
5366  if (state != NULL)
5367  {
5368  /* As per comment in transfn, strip data before the cursor position */
5370  state->len - state->cursor));
5371  }
5372  else
5373  PG_RETURN_NULL();
5374 }
5375 
5376 /*
5377  * Prepare cache with fmgr info for the output functions of the datatypes of
5378  * the arguments of a concat-like function, beginning with argument "argidx".
5379  * (Arguments before that will have corresponding slots in the resulting
5380  * FmgrInfo array, but we don't fill those slots.)
5381  */
5382 static FmgrInfo *
5384 {
5385  FmgrInfo *foutcache;
5386  int i;
5387 
5388  /* We keep the info in fn_mcxt so it survives across calls */
5389  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5390  PG_NARGS() * sizeof(FmgrInfo));
5391 
5392  for (i = argidx; i < PG_NARGS(); i++)
5393  {
5394  Oid valtype;
5395  Oid typOutput;
5396  bool typIsVarlena;
5397 
5398  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5399  if (!OidIsValid(valtype))
5400  elog(ERROR, "could not determine data type of concat() input");
5401 
5402  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5403  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5404  }
5405 
5406  fcinfo->flinfo->fn_extra = foutcache;
5407 
5408  return foutcache;
5409 }
5410 
5411 /*
5412  * Implementation of both concat() and concat_ws().
5413  *
5414  * sepstr is the separator string to place between values.
5415  * argidx identifies the first argument to concatenate (counting from zero);
5416  * note that this must be constant across any one series of calls.
5417  *
5418  * Returns NULL if result should be NULL, else text value.
5419  */
5420 static text *
5421 concat_internal(const char *sepstr, int argidx,
5422  FunctionCallInfo fcinfo)
5423 {
5424  text *result;
5426  FmgrInfo *foutcache;
5427  bool first_arg = true;
5428  int i;
5429 
5430  /*
5431  * concat(VARIADIC some-array) is essentially equivalent to
5432  * array_to_text(), ie concat the array elements with the given separator.
5433  * So we just pass the case off to that code.
5434  */
5435  if (get_fn_expr_variadic(fcinfo->flinfo))
5436  {
5437  ArrayType *arr;
5438 
5439  /* Should have just the one argument */
5440  Assert(argidx == PG_NARGS() - 1);
5441 
5442  /* concat(VARIADIC NULL) is defined as NULL */
5443  if (PG_ARGISNULL(argidx))
5444  return NULL;
5445 
5446  /*
5447  * Non-null argument had better be an array. We assume that any call
5448  * context that could let get_fn_expr_variadic return true will have
5449  * checked that a VARIADIC-labeled parameter actually is an array. So
5450  * it should be okay to just Assert that it's an array rather than
5451  * doing a full-fledged error check.
5452  */
5454 
5455  /* OK, safe to fetch the array value */
5456  arr = PG_GETARG_ARRAYTYPE_P(argidx);
5457 
5458  /*
5459  * And serialize the array. We tell array_to_text to ignore null
5460  * elements, which matches the behavior of the loop below.
5461  */
5462  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5463  }
5464 
5465  /* Normal case without explicit VARIADIC marker */
5466  initStringInfo(&str);
5467 
5468  /* Get output function info, building it if first time through */
5469  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5470  if (foutcache == NULL)
5471  foutcache = build_concat_foutcache(fcinfo, argidx);
5472 
5473  for (i = argidx; i < PG_NARGS(); i++)
5474  {
5475  if (!PG_ARGISNULL(i))
5476  {
5478 
5479  /* add separator if appropriate */
5480  if (first_arg)
5481  first_arg = false;
5482  else
5483  appendStringInfoString(&str, sepstr);
5484 
5485  /* call the appropriate type output function, append the result */
5487  OutputFunctionCall(&foutcache[i], value));
5488  }
5489  }
5490 
5491  result = cstring_to_text_with_len(str.data, str.len);
5492  pfree(str.data);
5493 
5494  return result;
5495 }
5496 
5497 /*
5498  * Concatenate all arguments. NULL arguments are ignored.
5499  */
5500 Datum
5502 {
5503  text *result;
5504 
5505  result = concat_internal("", 0, fcinfo);
5506  if (result == NULL)
5507  PG_RETURN_NULL();
5508  PG_RETURN_TEXT_P(result);
5509 }
5510 
5511 /*
5512  * Concatenate all but first argument value with separators. The first
5513  * parameter is used as the separator. NULL arguments are ignored.
5514  */
5515 Datum
5517 {
5518  char *sep;
5519  text *result;
5520 
5521  /* return NULL when separator is NULL */
5522  if (PG_ARGISNULL(0))
5523  PG_RETURN_NULL();
5525 
5526  result = concat_internal(sep, 1, fcinfo);
5527  if (result == NULL)
5528  PG_RETURN_NULL();
5529  PG_RETURN_TEXT_P(result);
5530 }
5531 
5532 /*
5533  * Return first n characters in the string. When n is negative,
5534  * return all but last |n| characters.
5535  */
5536 Datum
5538 {
5539  int n = PG_GETARG_INT32(1);
5540 
5541  if (n < 0)
5542  {
5543  text *str = PG_GETARG_TEXT_PP(0);
5544  const char *p = VARDATA_ANY(str);
5545  int len = VARSIZE_ANY_EXHDR(str);
5546  int rlen;
5547 
5548  n = pg_mbstrlen_with_len(p, len) + n;
5549  rlen = pg_mbcharcliplen(p, len, n);
5551  }
5552  else
5554 }
5555 
5556 /*
5557  * Return last n characters in the string. When n is negative,
5558  * return all but first |n| characters.
5559  */
5560 Datum
5562 {
5563  text *str = PG_GETARG_TEXT_PP(0);
5564  const char *p = VARDATA_ANY(str);
5565  int len = VARSIZE_ANY_EXHDR(str);
5566  int n = PG_GETARG_INT32(1);
5567  int off;
5568 
5569  if (n < 0)
5570  n = -n;
5571  else
5572  n = pg_mbstrlen_with_len(p, len) - n;
5573  off = pg_mbcharcliplen(p, len, n);
5574 
5576 }
5577 
5578 /*
5579  * Return reversed string
5580  */
5581 Datum
5583 {
5584  text *str = PG_GETARG_TEXT_PP(0);
5585  const char *p = VARDATA_ANY(str);
5586  int len = VARSIZE_ANY_EXHDR(str);
5587  const char *endp = p + len;
5588  text *result;
5589  char *dst;
5590 
5591  result = palloc(len + VARHDRSZ);
5592  dst = (char *) VARDATA(result) + len;
5593  SET_VARSIZE(result, len + VARHDRSZ);
5594 
5596  {
5597  /* multibyte version */
5598  while (p < endp)
5599  {
5600  int sz;
5601 
5602  sz = pg_mblen(p);
5603  dst -= sz;
5604  memcpy(dst, p, sz);
5605  p += sz;
5606  }
5607  }
5608  else
5609  {
5610  /* single byte version */
5611  while (p < endp)
5612  *(--dst) = *p++;
5613  }
5614 
5615  PG_RETURN_TEXT_P(result);
5616 }
5617 
5618 
5619 /*
5620  * Support macros for text_format()
5621  */
5622 #define TEXT_FORMAT_FLAG_MINUS 0x0001 /* is minus flag present? */
5623 
5624 #define ADVANCE_PARSE_POINTER(ptr,end_ptr) \
5625  do { \
5626  if (++(ptr) >= (end_ptr)) \
5627  ereport(ERROR, \
5628  (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
5629  errmsg("unterminated format() type specifier"), \
5630  errhint("For a single \"%%\" use \"%%%%\"."))); \
5631  } while (0)
5632 
5633 /*
5634  * Returns a formatted string
5635  */
5636 Datum
5638 {
5639  text *fmt;
5641  const char *cp;
5642  const char *start_ptr;
5643  const char *end_ptr;
5644  text *result;
5645  int arg;
5646  bool funcvariadic;
5647  int nargs;
5648  Datum *elements = NULL;
5649  bool *nulls = NULL;
5650  Oid element_type = InvalidOid;
5651  Oid prev_type = InvalidOid;
5652  Oid prev_width_type = InvalidOid;
5653  FmgrInfo typoutputfinfo;
5654  FmgrInfo typoutputinfo_width;
5655 
5656  /* When format string is null, immediately return null */
5657  if (PG_ARGISNULL(0))
5658  PG_RETURN_NULL();
5659 
5660  /* If argument is marked VARIADIC, expand array into elements */
5661  if (get_fn_expr_variadic(fcinfo->flinfo))
5662  {
5663  ArrayType *arr;
5664  int16 elmlen;
5665  bool elmbyval;
5666  char elmalign;
5667  int nitems;
5668 
5669  /* Should have just the one argument */
5670  Assert(PG_NARGS() == 2);
5671 
5672  /* If argument is NULL, we treat it as zero-length array */
5673  if (PG_ARGISNULL(1))
5674  nitems = 0;
5675  else
5676  {
5677  /*
5678  * Non-null argument had better be an array. We assume that any
5679  * call context that could let get_fn_expr_variadic return true
5680  * will have checked that a VARIADIC-labeled parameter actually is
5681  * an array. So it should be okay to just Assert that it's an
5682  * array rather than doing a full-fledged error check.
5683  */
5685 
5686  /* OK, safe to fetch the array value */
5687  arr = PG_GETARG_ARRAYTYPE_P(1);
5688 
5689  /* Get info about array element type */
5690  element_type = ARR_ELEMTYPE(arr);
5691  get_typlenbyvalalign(element_type,
5692  &elmlen, &elmbyval, &elmalign);
5693 
5694  /* Extract all array elements */
5695  deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
5696  &elements, &nulls, &nitems);
5697  }
5698 
5699  nargs = nitems + 1;
5700  funcvariadic = true;
5701  }
5702  else
5703  {
5704  /* Non-variadic case, we'll process the arguments individually */
5705  nargs = PG_NARGS();
5706  funcvariadic = false;
5707  }
5708 
5709  /* Setup for main loop. */
5710  fmt = PG_GETARG_TEXT_PP(0);
5711  start_ptr = VARDATA_ANY(fmt);
5712  end_ptr = start_ptr + VARSIZE_ANY_EXHDR(fmt);
5713  initStringInfo(&str);
5714  arg = 1; /* next argument position to print */
5715 
5716  /* Scan format string, looking for conversion specifiers. */
5717  for (cp = start_ptr; cp < end_ptr; cp++)
5718  {
5719  int argpos;
5720  int widthpos;
5721  int flags;
5722  int width;
5723  Datum value;
5724  bool isNull;
5725  Oid typid;
5726 
5727  /*
5728  * If it's not the start of a conversion specifier, just copy it to
5729  * the output buffer.
5730  */
5731  if (*cp != '%')
5732  {
5734  continue;
5735  }
5736 
5737  ADVANCE_PARSE_POINTER(cp, end_ptr);
5738 
5739  /* Easy case: %% outputs a single % */
5740  if (*cp == '%')
5741  {
5743  continue;
5744  }
5745 
5746  /* Parse the optional portions of the format specifier */
5747  cp = text_format_parse_format(cp, end_ptr,
5748  &argpos, &widthpos,
5749  &flags, &width);
5750 
5751  /*
5752  * Next we should see the main conversion specifier. Whether or not
5753  * an argument position was present, it's known that at least one
5754  * character remains in the string at this point. Experience suggests
5755  * that it's worth checking that that character is one of the expected
5756  * ones before we try to fetch arguments, so as to produce the least
5757  * confusing response to a mis-formatted specifier.
5758  */
5759  if (strchr("sIL", *cp) == NULL)
5760  ereport(ERROR,
5761  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5762  errmsg("unrecognized format() type specifier \"%.*s\"",
5763  pg_mblen(cp), cp),
5764  errhint("For a single \"%%\" use \"%%%%\".")));
5765 
5766  /* If indirect width was specified, get its value */
5767  if (widthpos >= 0)
5768  {
5769  /* Collect the specified or next argument position */
5770  if (widthpos > 0)
5771  arg = widthpos;
5772  if (arg >= nargs)
5773  ereport(ERROR,
5774  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5775  errmsg("too few arguments for format()")));
5776 
5777  /* Get the value and type of the selected argument */
5778  if (!funcvariadic)
5779  {
5781  isNull = PG_ARGISNULL(arg);
5782  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5783  }
5784  else
5785  {
5786  value = elements[arg - 1];
5787  isNull = nulls[arg - 1];
5788  typid = element_type;
5789  }
5790  if (!OidIsValid(typid))
5791  elog(ERROR, "could not determine data type of format() input");
5792 
5793  arg++;
5794 
5795  /* We can treat NULL width the same as zero */
5796  if (isNull)
5797  width = 0;
5798  else if (typid == INT4OID)
5799  width = DatumGetInt32(value);
5800  else if (typid == INT2OID)
5801  width = DatumGetInt16(value);
5802  else
5803  {
5804  /* For less-usual datatypes, convert to text then to int */
5805  char *str;
5806 
5807  if (typid != prev_width_type)
5808  {
5809  Oid typoutputfunc;
5810  bool typIsVarlena;
5811 
5812  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5813  fmgr_info(typoutputfunc, &typoutputinfo_width);
5814  prev_width_type = typid;
5815  }
5816 
5817  str = OutputFunctionCall(&typoutputinfo_width, value);
5818 
5819  /* pg_strtoint32 will complain about bad data or overflow */
5820  width = pg_strtoint32(str);
5821 
5822  pfree(str);
5823  }
5824  }
5825 
5826  /* Collect the specified or next argument position */
5827  if (argpos > 0)
5828  arg = argpos;
5829  if (arg >= nargs)
5830  ereport(ERROR,
5831  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5832  errmsg("too few arguments for format()")));
5833 
5834  /* Get the value and type of the selected argument */
5835  if (!funcvariadic)
5836  {
5838  isNull = PG_ARGISNULL(arg);
5839  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5840  }
5841  else
5842  {
5843  value = elements[arg - 1];
5844  isNull = nulls[arg - 1];
5845  typid = element_type;
5846  }
5847  if (!OidIsValid(typid))
5848  elog(ERROR, "could not determine data type of format() input");
5849 
5850  arg++;
5851 
5852  /*
5853  * Get the appropriate typOutput function, reusing previous one if
5854  * same type as previous argument. That's particularly useful in the
5855  * variadic-array case, but often saves work even for ordinary calls.
5856  */
5857  if (typid != prev_type)
5858  {
5859  Oid typoutputfunc;
5860  bool typIsVarlena;
5861 
5862  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5863  fmgr_info(typoutputfunc, &typoutputfinfo);
5864  prev_type = typid;
5865  }
5866 
5867  /*
5868  * And now we can format the value.
5869  */
5870  switch (*cp)
5871  {
5872  case 's':
5873  case 'I':
5874  case 'L':
5875  text_format_string_conversion(&str, *cp, &typoutputfinfo,
5876  value, isNull,
5877  flags, width);
5878  break;
5879  default:
5880  /* should not get here, because of previous check */
5881  ereport(ERROR,
5882  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5883  errmsg("unrecognized format() type specifier \"%.*s\"",
5884  pg_mblen(cp), cp),
5885  errhint("For a single \"%%\" use \"%%%%\".")));
5886  break;
5887  }
5888  }
5889 
5890  /* Don't need deconstruct_array results anymore. */
5891  if (elements != NULL)
5892  pfree(elements);
5893  if (nulls != NULL)
5894  pfree(nulls);
5895 
5896  /* Generate results. */
5897  result = cstring_to_text_with_len(str.data, str.len);
5898  pfree(str.data);
5899 
5900  PG_RETURN_TEXT_P(result);
5901 }
5902 
5903 /*
5904  * Parse contiguous digits as a decimal number.
5905  *
5906  * Returns true if some digits could be parsed.
5907  * The value is returned into *value, and *ptr is advanced to the next
5908  * character to be parsed.
5909  *
5910  * Note parsing invariant: at least one character is known available before
5911  * string end (end_ptr) at entry, and this is still true at exit.
5912  */
5913 static bool
5914 text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
5915 {
5916  bool found = false;
5917  const char *cp = *ptr;
5918  int val = 0;
5919 
5920  while (*cp >= '0' && *cp <= '9')
5921  {
5922  int8 digit = (*cp - '0');
5923 
5924  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5925  unlikely(pg_add_s32_overflow(val, digit, &val)))
5926  ereport(ERROR,
5927  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5928  errmsg("number is out of range")));
5929  ADVANCE_PARSE_POINTER(cp, end_ptr);
5930  found = true;
5931  }
5932 
5933  *ptr = cp;
5934  *value = val;
5935 
5936  return found;
5937 }
5938 
5939 /*
5940  * Parse a format specifier (generally following the SUS printf spec).
5941  *
5942  * We have already advanced over the initial '%', and we are looking for
5943  * [argpos][flags][width]type (but the type character is not consumed here).
5944  *
5945  * Inputs are start_ptr (the position after '%') and end_ptr (string end + 1).
5946  * Output parameters:
5947  * argpos: argument position for value to be printed. -1 means unspecified.
5948  * widthpos: argument position for width. Zero means the argument position
5949  * was unspecified (ie, take the next arg) and -1 means no width
5950  * argument (width was omitted or specified as a constant).
5951  * flags: bitmask of flags.
5952  * width: directly-specified width value. Zero means the width was omitted
5953  * (note it's not necessary to distinguish this case from an explicit
5954  * zero width value).
5955  *
5956  * The function result is the next character position to be parsed, ie, the
5957  * location where the type character is/should be.
5958  *
5959  * Note parsing invariant: at least one character is known available before
5960  * string end (end_ptr) at entry, and this is still true at exit.
5961  */
5962 static const char *
5963 text_format_parse_format(const char *start_ptr, const char *end_ptr,
5964  int *argpos, int *widthpos,
5965  int *flags, int *width)
5966 {
5967  const char *cp = start_ptr;
5968  int n;
5969 
5970  /* set defaults for output parameters */
5971  *argpos = -1;
5972  *widthpos = -1;
5973  *flags = 0;
5974  *width = 0;
5975 
5976  /* try to identify first number */
5977  if (text_format_parse_digits(&cp, end_ptr, &n))
5978  {
5979  if (*cp != '$')
5980  {
5981  /* Must be just a width and a type, so we're done */
5982  *width = n;
5983  return cp;
5984  }
5985  /* The number was argument position */
5986  *argpos = n;
5987  /* Explicit 0 for argument index is immediately refused */
5988  if (n == 0)
5989  ereport(ERROR,
5990  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5991  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5992  ADVANCE_PARSE_POINTER(cp, end_ptr);
5993  }
5994 
5995  /* Handle flags (only minus is supported now) */
5996  while (*cp == '-')
5997  {
5998  *flags |= TEXT_FORMAT_FLAG_MINUS;
5999  ADVANCE_PARSE_POINTER(cp, end_ptr);
6000  }
6001 
6002  if (*cp == '*')
6003  {
6004  /* Handle indirect width */
6005  ADVANCE_PARSE_POINTER(cp, end_ptr);
6006  if (text_format_parse_digits(&cp, end_ptr, &n))
6007  {
6008  /* number in this position must be closed by $ */
6009  if (*cp != '$')
6010  ereport(ERROR,
6011  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6012  errmsg("width argument position must be ended by \"$\"")));
6013  /* The number was width argument position */
6014  *widthpos = n;
6015  /* Explicit 0 for argument index is immediately refused */
6016  if (n == 0)
6017  ereport(ERROR,
6018  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6019  errmsg("format specifies argument 0, but arguments are numbered from 1")));
6020  ADVANCE_PARSE_POINTER(cp, end_ptr);
6021  }
6022  else
6023  *widthpos = 0; /* width's argument position is unspecified */
6024  }
6025  else
6026  {
6027  /* Check for direct width specification */
6028  if (text_format_parse_digits(&cp, end_ptr, &n))
6029  *width = n;
6030  }
6031 
6032  /* cp should now be pointing at type character */
6033  return cp;
6034 }
6035 
6036 /*
6037  * Format a %s, %I, or %L conversion
6038  */
6039 static void
6041  FmgrInfo *typOutputInfo,
6042  Datum value, bool isNull,
6043  int flags, int width)
6044 {
6045  char *str;
6046 
6047  /* Handle NULL arguments before trying to stringify the value. */
6048  if (isNull)
6049  {
6050  if (conversion == 's')
6051  text_format_append_string(buf, "", flags, width);
6052  else if (conversion == 'L')
6053  text_format_append_string(buf, "NULL", flags, width);
6054  else if (conversion == 'I')
6055  ereport(ERROR,
6056  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6057  errmsg("null values cannot be formatted as an SQL identifier")));
6058  return;
6059  }
6060 
6061  /* Stringify. */
6062  str = OutputFunctionCall(typOutputInfo, value);
6063 
6064  /* Escape. */
6065  if (conversion == 'I')
6066  {
6067  /* quote_identifier may or may not allocate a new string. */
6069  }
6070  else if (conversion == 'L')
6071  {
6072  char *qstr = quote_literal_cstr(str);
6073 
6074  text_format_append_string(buf, qstr, flags, width);
6075  /* quote_literal_cstr() always allocates a new string */
6076  pfree(qstr);
6077  }
6078  else
6079  text_format_append_string(buf, str, flags, width);
6080 
6081  /* Cleanup. */
6082  pfree(str);
6083 }
6084 
6085 /*
6086  * Append str to buf, padding as directed by flags/width
6087  */
6088 static void
6090  int flags, int width)
6091 {
6092  bool align_to_left = false;
6093  int len;
6094 
6095  /* fast path for typical easy case */
6096  if (width == 0)
6097  {
6099  return;
6100  }
6101 
6102  if (width < 0)
6103  {
6104  /* Negative width: implicit '-' flag, then take absolute value */
6105  align_to_left = true;
6106  /* -INT_MIN is undefined */
6107  if (width <= INT_MIN)
6108  ereport(ERROR,
6109  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6110  errmsg("number is out of range")));
6111  width = -width;
6112  }
6113  else if (flags & TEXT_FORMAT_FLAG_MINUS)
6114  align_to_left = true;
6115 
6116  len = pg_mbstrlen(str);
6117  if (align_to_left)
6118  {
6119  /* left justify */
6121  if (len < width)
6122  appendStringInfoSpaces(buf, width - len);
6123  }
6124  else
6125  {
6126  /* right justify */
6127  if (len < width)
6128  appendStringInfoSpaces(buf, width - len);
6130  }
6131 }
6132 
6133 /*
6134  * text_format_nv - nonvariadic wrapper for text_format function.
6135  *
6136  * note: this wrapper is necessary to pass the sanity check in opr_sanity,
6137  * which checks that all built-in functions that share the implementing C
6138  * function take the same number of arguments.
6139  */
6140 Datum
6142 {
6143  return text_format(fcinfo);
6144 }
6145 
6146 /*
6147  * Helper function for Levenshtein distance functions. Faster than memcmp(),
6148  * for this use case.
6149  */
6150 static inline bool
6151 rest_of_char_same(const char *s1, const char *s2, int len)
6152 {
6153  while (len > 0)
6154  {
6155  len--;
6156  if (s1[len] != s2[len])
6157  return false;
6158  }
6159  return true;
6160 }
6161 
6162 /* Expand each Levenshtein distance variant */
6163 #include "levenshtein.c"
6164 #define LEVENSHTEIN_LESS_EQUAL
6165 #include "levenshtein.c"
6166 
6167 
6168 /*
6169  * The following *ClosestMatch() functions can be used to determine whether a
6170  * user-provided string resembles any known valid values, which is useful for
6171  * providing hints in log messages, among other things. Use these functions
6172  * like so:
6173  *
6174  * initClosestMatch(&state, source_string, max_distance);
6175  *
6176  * for (int i = 0; i < num_valid_strings; i++)
6177  * updateClosestMatch(&state, valid_strings[i]);
6178  *
6179  * closestMatch = getClosestMatch(&state);
6180  */
6181 
6182 /*
6183  * Initialize the given state with the source string and maximum Levenshtein
6184  * distance to consider.
6185  */
6186 void
6188 {
6189  Assert(state);
6190  Assert(max_d >= 0);
6191 
6192  state->source = source;
6193  state->min_d = -1;
6194  state->max_d = max_d;
6195  state->match = NULL;
6196 }
6197 
6198 /*
6199  * If the candidate string is a closer match than the current one saved (or
6200  * there is no match saved), save it as the closest match.
6201  *
6202  * If the source or candidate string is NULL, empty, or too long, this function
6203  * takes no action. Likewise, if the Levenshtein distance exceeds the maximum
6204  * allowed or more than half the characters are different, no action is taken.
6205  */
6206 void
6208 {
6209  int dist;
6210 
6211  Assert(state);
6212 
6213  if (state->source == NULL || state->source[0] == '\0' ||
6214  candidate == NULL || candidate[0] == '\0')
6215  return;
6216 
6217  /*
6218  * To avoid ERROR-ing, we check the lengths here instead of setting
6219  * 'trusted' to false in the call to varstr_levenshtein_less_equal().
6220  */
6221  if (strlen(state->source) > MAX_LEVENSHTEIN_STRLEN ||
6222  strlen(candidate) > MAX_LEVENSHTEIN_STRLEN)
6223  return;
6224 
6225  dist = varstr_levenshtein_less_equal(state->source, strlen(state->source),
6226  candidate, strlen(candidate), 1, 1, 1,
6227  state->max_d, true);
6228  if (dist <= state->max_d &&
6229  dist <= strlen(state->source) / 2 &&
6230  (state->min_d == -1 || dist < state->min_d))
6231  {
6232  state->min_d = dist;
6233  state->match = candidate;
6234  }
6235 }
6236 
6237 /*
6238  * Return the closest match. If no suitable candidates were provided via
6239  * updateClosestMatch(), return NULL.
6240  */
6241 const char *
6243 {
6244  Assert(state);
6245 
6246  return state->match;
6247 }
6248 
6249 
6250 /*
6251  * Unicode support
6252  */
6253 
6255 unicode_norm_form_from_string(const char *formstr)
6256 {
6257  UnicodeNormalizationForm form = -1;
6258 
6259  /*
6260  * Might as well check this while we're here.
6261  */
6262  if (GetDatabaseEncoding() != PG_UTF8)
6263  ereport(ERROR,
6264  (errcode(ERRCODE_SYNTAX_ERROR),
6265  errmsg("Unicode normalization can only be performed if server encoding is UTF8")));
6266 
6267  if (pg_strcasecmp(formstr, "NFC") == 0)
6268  form = UNICODE_NFC;
6269  else if (pg_strcasecmp(formstr, "NFD") == 0)
6270  form = UNICODE_NFD;
6271  else if (pg_strcasecmp(formstr, "NFKC") == 0)
6272  form = UNICODE_NFKC;
6273  else if (pg_strcasecmp(formstr, "NFKD") == 0)
6274  form = UNICODE_NFKD;
6275  else
6276  ereport(ERROR,
6277  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6278  errmsg("invalid normalization form: %s", formstr)));
6279 
6280  return form;
6281 }
6282 
6283 /*
6284  * Returns version of Unicode used by Postgres in "major.minor" format (the
6285  * same format as the Unicode version reported by ICU). The third component
6286  * ("update version") never involves additions to the character repertiore and
6287  * is unimportant for most purposes.
6288  *
6289  * See: https://unicode.org/versions/
6290  */
6291 Datum
6293 {
6295 }
6296 
6297 /*
6298  * Returns version of Unicode used by ICU, if enabled; otherwise NULL.
6299  */
6300 Datum
6302 {
6303 #ifdef USE_ICU
6304  PG_RETURN_TEXT_P(cstring_to_text(U_UNICODE_VERSION));
6305 #else
6306  PG_RETURN_NULL();
6307 #endif
6308 }
6309 
6310 /*
6311  * Check whether the string contains only assigned Unicode code
6312  * points. Requires that the database encoding is UTF-8.
6313  */
6314 Datum
6316 {
6318  unsigned char *p;
6319  int size;
6320 
6321  if (GetDatabaseEncoding() != PG_UTF8)
6322  ereport(ERROR,
6323  (errmsg("Unicode categorization can only be performed if server encoding is UTF8")));
6324 
6325  /* convert to pg_wchar */
6327  p = (unsigned char *) VARDATA_ANY(input);
6328  for (int i = 0; i < size; i++)
6329  {
6330  pg_wchar uchar = utf8_to_unicode(p);
6331  int category = unicode_category(uchar);
6332 
6333  if (category == PG_U_UNASSIGNED)
6334  PG_RETURN_BOOL(false);
6335 
6336  p += pg_utf_mblen(p);
6337  }
6338 
6339  PG_RETURN_BOOL(true);
6340 }
6341 
6342 Datum
6344 {
6346  char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
6348  int size;
6349  pg_wchar *input_chars;
6350  pg_wchar *output_chars;
6351  unsigned char *p;
6352  text *result;
6353  int i;
6354 
6355  form = unicode_norm_form_from_string(formstr);
6356 
6357  /* convert to pg_wchar */
6359  input_chars = palloc((size + 1) * sizeof(pg_wchar));
6360  p = (unsigned char *) VARDATA_ANY(input);
6361  for (i = 0; i < size; i++)
6362  {
6363  input_chars[i] = utf8_to_unicode(p);
6364  p += pg_utf_mblen(p);
6365  }
6366  input_chars[i] = (pg_wchar) '\0';
6367  Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
6368 
6369  /* action */
6370  output_chars = unicode_normalize(form, input_chars);
6371 
6372  /* convert back to UTF-8 string */
6373  size = 0;
6374  for (pg_wchar *wp = output_chars; *wp; wp++)
6375  {
6376  unsigned char buf[4];
6377 
6378  unicode_to_utf8(*wp, buf);
6379  size += pg_utf_mblen(buf);
6380  }
6381 
6382  result = palloc(size + VARHDRSZ);
6383  SET_VARSIZE(result, size + VARHDRSZ);
6384 
6385  p = (unsigned char *) VARDATA_ANY(result);
6386  for (pg_wchar *wp = output_chars; *wp; wp++)
6387  {
6388  unicode_to_utf8(*wp, p);
6389  p += pg_utf_mblen(p);
6390  }
6391  Assert((char *) p == (char *) result + size + VARHDRSZ);
6392 
6393  PG_RETURN_TEXT_P(result);
6394 }
6395 
6396 /*
6397  * Check whether the string is in the specified Unicode normalization form.
6398  *
6399  * This is done by converting the string to the specified normal form and then
6400  * comparing that to the original string. To speed that up, we also apply the
6401  * "quick check" algorithm specified in UAX #15, which can give a yes or no
6402  * answer for many strings by just scanning the string once.
6403  *
6404  * This function should generally be optimized for the case where the string
6405  * is in fact normalized. In that case, we'll end up looking at the entire
6406  * string, so it's probably not worth doing any incremental conversion etc.
6407  */
6408 Datum
6410 {
6412  char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
6414  int size;
6415  pg_wchar *input_chars;
6416  pg_wchar *output_chars;
6417  unsigned char *p;
6418  int i;
6419  UnicodeNormalizationQC quickcheck;
6420  int output_size;
6421  bool result;
6422 
6423  form = unicode_norm_form_from_string(formstr);
6424 
6425  /* convert to pg_wchar */
6427  input_chars = palloc((size + 1) * sizeof(pg_wchar));
6428  p = (unsigned char *) VARDATA_ANY(input);
6429  for (i = 0; i < size; i++)
6430  {
6431  input_chars[i] = utf8_to_unicode(p);
6432  p += pg_utf_mblen(p);
6433  }
6434  input_chars[i] = (pg_wchar) '\0';
6435  Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
6436 
6437  /* quick check (see UAX #15) */
6438  quickcheck = unicode_is_normalized_quickcheck(form, input_chars);
6439  if (quickcheck == UNICODE_NORM_QC_YES)
6440  PG_RETURN_BOOL(true);
6441  else if (quickcheck == UNICODE_NORM_QC_NO)
6442  PG_RETURN_BOOL(false);
6443 
6444  /* normalize and compare with original */
6445  output_chars = unicode_normalize(form, input_chars);
6446 
6447  output_size = 0;
6448  for (pg_wchar *wp = output_chars; *wp; wp++)
6449  output_size++;
6450 
6451  result = (size == output_size) &&
6452  (memcmp(input_chars, output_chars, size * sizeof(pg_wchar)) == 0);
6453 
6454  PG_RETURN_BOOL(result);
6455 }
6456 
6457 /*
6458  * Check if first n chars are hexadecimal digits
6459  */
6460 static bool
6461 isxdigits_n(const char *instr, size_t n)
6462 {
6463  for (size_t i = 0; i < n; i++)
6464  if (!isxdigit((unsigned char) instr[i]))
6465  return false;
6466 
6467  return true;
6468 }
6469 
6470 static unsigned int
6471 hexval(unsigned char c)
6472 {
6473  if (c >= '0' && c <= '9')
6474  return c - '0';
6475  if (c >= 'a' && c <= 'f')
6476  return c - 'a' + 0xA;
6477  if (c >= 'A' && c <= 'F')
6478  return c - 'A' + 0xA;
6479  elog(ERROR, "invalid hexadecimal digit");
6480  return 0; /* not reached */
6481 }
6482 
6483 /*
6484  * Translate string with hexadecimal digits to number
6485  */
6486 static unsigned int
6487 hexval_n(const char *instr, size_t n)
6488 {
6489  unsigned int result = 0;
6490 
6491  for (size_t i = 0; i < n; i++)
6492  result += hexval(instr[i]) << (4 * (n - i - 1));
6493 
6494  return result;
6495 }
6496 
6497 /*
6498  * Replaces Unicode escape sequences by Unicode characters
6499  */
6500 Datum
6502 {
6503  text *input_text = PG_GETARG_TEXT_PP(0);
6504  char *instr;
6505  int len;
6507  text *result;
6508  pg_wchar pair_first = 0;
6509  char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
6510 
6511  instr = VARDATA_ANY(input_text);
6512  len = VARSIZE_ANY_EXHDR(input_text);
6513 
6514  initStringInfo(&str);
6515 
6516  while (len > 0)
6517  {
6518  if (instr[0] == '\\')
6519  {
6520  if (len >= 2 &&
6521  instr[1] == '\\')
6522  {
6523  if (pair_first)
6524  goto invalid_pair;
6525  appendStringInfoChar(&str, '\\');
6526  instr += 2;
6527  len -= 2;
6528  }
6529  else if ((len >= 5 && isxdigits_n(instr + 1, 4)) ||
6530  (len >= 6 && instr[1] == 'u' && isxdigits_n(instr + 2, 4)))
6531  {
6532  pg_wchar unicode;
6533  int offset = instr[1] == 'u' ? 2 : 1;
6534 
6535  unicode = hexval_n(instr + offset, 4);
6536 
6537  if (!is_valid_unicode_codepoint(unicode))
6538  ereport(ERROR,
6539  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6540  errmsg("invalid Unicode code point: %04X", unicode));
6541 
6542  if (pair_first)
6543  {
6544  if (is_utf16_surrogate_second(unicode))
6545  {
6546  unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6547  pair_first = 0;
6548  }
6549  else
6550  goto invalid_pair;
6551  }
6552  else if (is_utf16_surrogate_second(unicode))
6553  goto invalid_pair;
6554 
6555  if (is_utf16_surrogate_first(unicode))
6556  pair_first = unicode;
6557  else
6558  {
6559  pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6560  appendStringInfoString(&str, cbuf);
6561  }
6562 
6563  instr += 4 + offset;
6564  len -= 4 + offset;
6565  }
6566  else if (len >= 8 && instr[1] == '+' && isxdigits_n(instr + 2, 6))
6567  {
6568  pg_wchar unicode;
6569 
6570  unicode = hexval_n(instr + 2, 6);
6571 
6572  if (!is_valid_unicode_codepoint(unicode))
6573  ereport(ERROR,
6574  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6575  errmsg("invalid Unicode code point: %04X", unicode));
6576 
6577  if (pair_first)
6578  {
6579  if (is_utf16_surrogate_second(unicode))
6580  {
6581  unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6582  pair_first = 0;
6583  }
6584  else
6585  goto invalid_pair;
6586  }
6587  else if (is_utf16_surrogate_second(unicode))
6588  goto invalid_pair;
6589 
6590  if (is_utf16_surrogate_first(unicode))
6591  pair_first = unicode;
6592  else
6593  {
6594  pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6595  appendStringInfoString(&str, cbuf);
6596  }
6597 
6598  instr += 8;
6599  len -= 8;
6600  }
6601  else if (len >= 10 && instr[1] == 'U' && isxdigits_n(instr + 2, 8))
6602  {
6603  pg_wchar unicode;
6604 
6605  unicode = hexval_n(instr + 2, 8);
6606 
6607  if (!is_valid_unicode_codepoint(unicode))
6608  ereport(ERROR,
6609  errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6610  errmsg("invalid Unicode code point: %04X", unicode));
6611 
6612  if (pair_first)
6613  {
6614  if (is_utf16_surrogate_second(unicode))
6615  {
6616  unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6617  pair_first = 0;
6618  }
6619  else
6620  goto invalid_pair;
6621  }
6622  else if (is_utf16_surrogate_second(unicode))
6623  goto invalid_pair;
6624 
6625  if (is_utf16_surrogate_first(unicode))
6626  pair_first = unicode;
6627  else
6628  {
6629  pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6630  appendStringInfoString(&str, cbuf);
6631  }
6632 
6633  instr += 10;
6634  len -= 10;
6635  }
6636  else
6637  ereport(ERROR,
6638  (errcode(ERRCODE_SYNTAX_ERROR),
6639  errmsg("invalid Unicode escape"),
6640  errhint("Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX.")));
6641  }
6642  else
6643  {
6644  if (pair_first)
6645  goto invalid_pair;
6646 
6647  appendStringInfoChar(&str, *instr++);
6648  len--;
6649  }
6650  }
6651 
6652  /* unfinished surrogate pair? */
6653  if (pair_first)
6654  goto invalid_pair;
6655 
6656  result = cstring_to_text_with_len(str.data, str.len);
6657  pfree(str.data);
6658 
6659  PG_RETURN_TEXT_P(result);
6660 
6661 invalid_pair:
6662  ereport(ERROR,
6663  (errcode(ERRCODE_SYNTAX_ERROR),
6664  errmsg("invalid Unicode surrogate pair")));
6665  PG_RETURN_NULL(); /* keep compiler quiet */
6666 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define ARR_NDIM(a)
Definition: array.h:290
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define ARR_NULLBITMAP(a)
Definition: array.h:300
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:265
#define ARR_DIMS(a)
Definition: array.h:294
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5331
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3561
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3612
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5401
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
static Datum values[MAXATTR]
Definition: bootstrap.c:152
#define TextDatumGetCString(d)
Definition: builtins.h:98
@ BYTEA_OUTPUT_HEX
Definition: bytea.h:22
@ BYTEA_OUTPUT_ESCAPE
Definition: bytea.h:21
#define NameStr(name)
Definition: c.h:733
#define unconstify(underlying_type, expr)
Definition: c.h:1232
unsigned int uint32
Definition: c.h:493
NameData * Name
Definition: c.h:731
signed char int8
Definition: c.h:479
#define Min(x, y)
Definition: c.h:991
signed short int16
Definition: c.h:480
signed int int32
Definition: c.h:481
#define Max(x, y)
Definition: c.h:985
#define VARHDRSZ
Definition: c.h:679
uint8 bits8
Definition: c.h:500
#define unlikely(x)
Definition: c.h:298
#define lengthof(array)
Definition: c.h:775
#define OidIsValid(objectId)
Definition: c.h:762
size_t Size
Definition: c.h:592
Oid collid
Size toast_datum_size(Datum value)
Definition: detoast.c:601
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr)
Definition: detoast.h:22
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
int errhint(const char *fmt,...)
Definition: elog.c:1319
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define LOG
Definition: elog.h:31
#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
uint64 hex_decode_safe(const char *src, size_t len, char *dst, Node *escontext)
Definition: encode.c:196
uint64 hex_encode(const char *src, size_t len, char *dst)
Definition: encode.c:162
struct varlena * pg_detoast_datum_packed(struct varlena *datum)
Definition: fmgr.c:1864
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:812
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2044
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1910
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:303
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
#define DatumGetTextPP(X)
Definition: fmgr.h:292
#define DatumGetBpCharPP(X)
Definition: fmgr.h:293
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
struct FmgrInfo FmgrInfo
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_NARGS()
Definition: fmgr.h:203
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define DatumGetTextPSlice(X, m, n)
Definition: fmgr.h:304
#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_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition: funcapi.h:296
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
Definition: hyperloglog.c:66
double estimateHyperLogLog(hyperLogLogState *cState)
Definition: hyperloglog.c:186
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
Definition: hyperloglog.c:167
#define nitems(x)
Definition: indent.h:31
FILE * input
long val
Definition: informix.c:664
int digits
Definition: informix.c:666
static struct @150 value
static char * locale
Definition: initdb.c:140
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int y
Definition: isn.c:72
int x
Definition: isn.c:71
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
#define MAX_LEVENSHTEIN_STRLEN
Definition: levenshtein.c:26
static void const char * fmt
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:339
void list_free(List *list)
Definition: list.c:1546
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2863
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2227
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:1054
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
Definition: lsyscache.c:2281
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2153
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2788
@ IOFunc_output
Definition: lsyscache.h:36
unsigned int pg_wchar
Definition: mbprint.c:31
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
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_mbstrlen(const char *mbstr)
Definition: mbutils.c:1037
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1083
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:864
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:986
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023
char * pstrdup(const char *in)
Definition: mcxt.c:1683
void pfree(void *pointer)
Definition: mcxt.c:1508
void * palloc0(Size size)
Definition: mcxt.c:1334
MemoryContext CurrentMemoryContext
Definition: mcxt.c:131
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1528
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1168
void * palloc(Size size)
Definition: mcxt.c:1304
#define MaxAllocSize
Definition: memutils.h:40
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4511
int32 pg_strtoint32(const char *s)
Definition: numutils.c:383
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void * arg
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:296
#define BITS_PER_BYTE
#define NAMEDATALEN
#define MAXPGPATH
#define PG_CACHE_LINE_SIZE
const void size_t len
const void * data
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
bool pg_strxfrm_enabled(pg_locale_t locale)
Definition: pg_locale.c:2328
int pg_strncoll(const char *arg1, size_t len1, const char *arg2, size_t len2, pg_locale_t locale)
Definition: pg_locale.c:2112
bool lc_collate_is_c(Oid collation)
Definition: pg_locale.c:1311
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1545
bool pg_locale_deterministic(pg_locale_t locale)
Definition: pg_locale.c:1525
int pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale)
Definition: pg_locale.c:2077
bool pg_strxfrm_prefix_enabled(pg_locale_t locale)
Definition: pg_locale.c:2419
size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale)
Definition: pg_locale.c:2360
size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, pg_locale_t locale)
Definition: pg_locale.c:2446
static rewind_source * source
Definition: pg_rewind.c:89
static char * buf
Definition: pg_test_fsync.c:73
char typalign
Definition: pg_type.h:176
#define pg_utf_mblen
Definition: pg_wchar.h:572
@ PG_UTF8
Definition: pg_wchar.h:232
#define MAX_UNICODE_EQUIVALENT_STRING
Definition: pg_wchar.h:329
static bool is_valid_unicode_codepoint(pg_wchar c)
Definition: pg_wchar.h:519
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
Definition: pg_wchar.h:537
static bool is_utf16_surrogate_first(pg_wchar c)
Definition: pg_wchar.h:525
static bool is_utf16_surrogate_second(pg_wchar c)
Definition: pg_wchar.h:531
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void canonicalize_path(char *path)
Definition: path.c:264
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:222
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
static Name DatumGetName(Datum X)
Definition: postgres.h:360
static char * DatumGetCString(Datum X)
Definition: postgres.h:335
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
static int16 DatumGetInt16(Datum X)
Definition: postgres.h:162
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:635
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:528
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:508
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint(StringInfo buf, uint32 i, int b)
Definition: pqformat.h:171
char * c
char * s1
char * s2
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:103
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
#define REG_NOMATCH
Definition: regex.h:138
#define REG_OKAY
Definition: regex.h:137
#define REG_NOSUB
Definition: regex.h:107
int pg_regexec(regex_t *re, const chr *string, size_t len, size_t search_start, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags)
Definition: regexec.c:185
regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation)
Definition: regexp.c:141
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11987
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:93
bool scanner_isspace(char ch)
Definition: scansup.c:117
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
#define S(n, x)
Definition: sha1.c:73
static pg_noinline void Size size
Definition: slab.c:607
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:212
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
StringInfoData * StringInfo
Definition: stringinfo.h:54
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:204
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:130
Oid typioparam
Definition: array.h:243
char typalign
Definition: array.h:241
Oid typiofunc
Definition: array.h:244
int16 typlen
Definition: array.h:239
Oid element_type
Definition: array.h:238
FmgrInfo proc
Definition: array.h:245
char typdelim
Definition: array.h:242
bool typbyval
Definition: array.h:240
Definition: fmgr.h:57
void * fn_extra
Definition: fmgr.h:64
MemoryContext fn_mcxt
Definition: fmgr.h:65
FmgrInfo * flinfo
Definition: fmgr.h:87
Definition: pg_list.h:54
Definition: nodes.h:129
TupleDesc setDesc
Definition: execnodes.h:340
Tuplestorestate * setResult
Definition: execnodes.h:339
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:172
void * ssup_extra
Definition: sortsupport.h:87
MemoryContext ssup_cxt
Definition: sortsupport.h:66
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:191
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
Definition: sortsupport.h:182
TupleDesc tupdesc
Definition: varlena.c:107
ArrayBuildState * astate
Definition: varlena.c:105
Tuplestorestate * tupstore
Definition: varlena.c:106
bool is_multibyte_char_in_char
Definition: varlena.c:57
char * last_match
Definition: varlena.c:68
char * refpoint
Definition: varlena.c:76
pg_locale_t locale
Definition: varlena.c:96
hyperLogLogState full_card
Definition: varlena.c:94
hyperLogLogState abbr_card
Definition: varlena.c:93
Definition: c.h:728
Definition: regex.h:56
regoff_t rm_eo
Definition: regex.h:86
regoff_t rm_so
Definition: regex.h:85
Definition: regguts.h:323
Oid va_valueid
Definition: varatt.h:37
Definition: c.h:674
ToastCompressionId toast_get_compression_id(struct varlena *attr)
ToastCompressionId
@ TOAST_INVALID_COMPRESSION_ID
@ TOAST_LZ4_COMPRESSION_ID
@ TOAST_PGLZ_COMPRESSION_ID
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3171
bool trace_sort
Definition: tuplesort.c:124
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:750
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:129
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:157
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition: tupmacs.h:52
pg_unicode_category unicode_category(pg_wchar code)
@ PG_U_UNASSIGNED
UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input)
Definition: unicode_norm.c:598
pg_wchar * unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
Definition: unicode_norm.c:402
UnicodeNormalizationForm
Definition: unicode_norm.h:20
@ UNICODE_NFKD
Definition: unicode_norm.h:24
@ UNICODE_NFD
Definition: unicode_norm.h:22
@ UNICODE_NFC
Definition: unicode_norm.h:21
@ UNICODE_NFKC
Definition: unicode_norm.h:23
UnicodeNormalizationQC
Definition: unicode_norm.h:29
@ UNICODE_NORM_QC_YES
Definition: unicode_norm.h:31
@ UNICODE_NORM_QC_NO
Definition: unicode_norm.h:30
#define PG_UNICODE_VERSION
String * makeString(char *str)
Definition: value.c:63
#define VARATT_IS_EXTERNAL_ONDISK(PTR)
Definition: varatt.h:290
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311
#define VARDATA(PTR)
Definition: varatt.h:278
#define VARATT_IS_COMPRESSED(PTR)
Definition: varatt.h:288
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305
#define VARSIZE(PTR)
Definition: varatt.h:279
#define VARATT_IS_EXTERNAL(PTR)
Definition: varatt.h:289
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
int bpchartruelen(char *s, int len)
Definition: varchar.c:676
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2138
static text * convert_to_base(uint64 value, int base)
Definition: varlena.c:4929
Datum byteacat(PG_FUNCTION_ARGS)
Definition: varlena.c:2937
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3398
Datum unknownrecv(PG_FUNCTION_ARGS)
Definition: varlena.c:658
Datum array_to_text(PG_FUNCTION_ARGS)
Definition: varlena.c:4765
Datum byteaoverlay(PG_FUNCTION_ARGS)
Definition: varlena.c:3094
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1593
Datum textsend(PG_FUNCTION_ARGS)
Definition: varlena.c:619
Datum textoverlay_no_len(PG_FUNCTION_ARGS)
Definition: varlena.c:1103
static void text_format_string_conversion(StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
Definition: varlena.c:6040
const char * getClosestMatch(ClosestMatchState *state)
Definition: varlena.c:6242
static text * text_overlay(text *t1, text *t2, int sp, int sl)
Definition: varlena.c:1115
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5637
Datum textlen(PG_FUNCTION_ARGS)
Definition: varlena.c:693
Datum pg_column_toast_chunk_id(PG_FUNCTION_ARGS)
Definition: varlena.c:5113
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1215
int bytea_output
Definition: varlena.c:48
static int32 text_length(Datum str)
Definition: varlena.c:711
static bool varstr_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: varlena.c:2436
Datum byteaeq(PG_FUNCTION_ARGS)
Definition: varlena.c:3793
Datum text_left(PG_FUNCTION_ARGS)
Definition: varlena.c:5537
#define DIG(VAL)
Definition: varlena.c:276
Datum byteagt(PG_FUNCTION_ARGS)
Definition: varlena.c:3897
Datum string_agg_transfn(PG_FUNCTION_ARGS)
Definition: varlena.c:5185
static bool text_isequal(text *txt1, text *txt2, Oid collid)
Definition: varlena.c:4499
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1502
static text * text_catenate(text *t1, text *t2)
Definition: varlena.c:765
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3981
Datum textgtname(PG_FUNCTION_ARGS)
Definition: varlena.c:2773
Datum textout(PG_FUNCTION_ARGS)
Definition: varlena.c:590
Datum textcat(PG_FUNCTION_ARGS)
Definition: varlena.c:750
Datum text_substr(PG_FUNCTION_ARGS)
Definition: varlena.c:852
Datum bytea_string_agg_finalfn(PG_FUNCTION_ARGS)
Definition: varlena.c:551
Datum text_smaller(PG_FUNCTION_ARGS)
Definition: varlena.c:2582
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:885
static int check_replace_text_has_escape(const text *replace_text)
Definition: varlena.c:4072
Datum text_concat_ws(PG_FUNCTION_ARGS)
Definition: varlena.c:5516
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2796
Datum string_agg_serialize(PG_FUNCTION_ARGS)
Definition: varlena.c:5290
Datum text_ge(PG_FUNCTION_ARGS)
Definition: varlena.c:1775
static int varlenafastcmp_locale(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2093
Datum array_to_text_null(PG_FUNCTION_ARGS)
Definition: varlena.c:4781
static const char * text_format_parse_format(const char *start_ptr, const char *end_ptr, int *argpos, int *widthpos, int *flags, int *width)
Definition: varlena.c:5963
Datum text_larger(PG_FUNCTION_ARGS)
Definition: varlena.c:2570
Datum byteapos(PG_FUNCTION_ARGS)
Definition: varlena.c:3164
Datum unicode_assigned(PG_FUNCTION_ARGS)
Definition: varlena.c:6315
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3117
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1538
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1467
static int bpcharfastcmp_c(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2048
Datum text_to_array_null(PG_FUNCTION_ARGS)
Definition: varlena.c:4539
static unsigned int hexval_n(const char *instr, size_t n)
Definition: varlena.c:6487
Datum byteane(PG_FUNCTION_ARGS)
Definition: varlena.c:3825
static bool rest_of_char_same(const char *s1, const char *s2, int len)
Definition: varlena.c:6151
Datum byteage(PG_FUNCTION_ARGS)
Definition: varlena.c:3917
Datum byteacmp(PG_FUNCTION_ARGS)
Definition: varlena.c:3937
Datum text_to_table_null(PG_FUNCTION_ARGS)
Definition: varlena.c:4574
Datum text_right(PG_FUNCTION_ARGS)
Definition: varlena.c:5561
Datum textne(PG_FUNCTION_ARGS)
Definition: varlena.c:1677
Datum textrecv(PG_FUNCTION_ARGS)
Definition: varlena.c:601
Datum byteaGetBit(PG_FUNCTION_ARGS)
Definition: varlena.c:3237
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:6089
static int text_position(text *t1, text *t2, Oid collid)
Definition: varlena.c:1175
bool SplitDirectoriesString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3583
Datum bytea_bit_count(PG_FUNCTION_ARGS)
Definition: varlena.c:3150
Datum unicode_normalize_func(PG_FUNCTION_ARGS)
Definition: varlena.c:6343
Datum bttext_pattern_sortsupport(PG_FUNCTION_ARGS)
Definition: varlena.c:2898
static void split_text_accum_result(SplitTextOutputData *tstate, text *field_value, text *null_string, Oid collation)
Definition: varlena.c:4726
Datum byteaSetBit(PG_FUNCTION_ARGS)
Definition: varlena.c:3307
Datum split_part(PG_FUNCTION_ARGS)
Definition: varlena.c:4367
Datum texteqname(PG_FUNCTION_ARGS)
Definition: varlena.c:2624
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5383
Datum text_substr_no_len(PG_FUNCTION_ARGS)
Definition: varlena.c:866
Datum text_name(PG_FUNCTION_ARGS)
Definition: varlena.c:3358
Datum byteaSetByte(PG_FUNCTION_ARGS)
Definition: varlena.c:3275
Datum text_le(PG_FUNCTION_ARGS)
Definition: varlena.c:1745
static void text_position_reset(TextPositionState *state)
Definition: varlena.c:1494
Datum text_to_table(PG_FUNCTION_ARGS)
Definition: varlena.c:4550
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5624
Datum textnename(PG_FUNCTION_ARGS)
Definition: varlena.c:2674
static char * text_position_next_internal(char *start_ptr, TextPositionState *state)
Definition: varlena.c:1399
Datum to_hex64(PG_FUNCTION_ARGS)
Definition: varlena.c:5000
Datum text_to_array(PG_FUNCTION_ARGS)
Definition: varlena.c:4513
Datum bytea_substr_no_len(PG_FUNCTION_ARGS)
Definition: varlena.c:3018
Datum unicode_is_normalized(PG_FUNCTION_ARGS)
Definition: varlena.c:6409
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5622
static void check_collation_set(Oid collid)
Definition: varlena.c:1509
bool SplitGUCList(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3704
char * text_to_cstring(const text *t)
Definition: varlena.c:217
Datum textoverlay(PG_FUNCTION_ARGS)
Definition: varlena.c:1092
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4105
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3456
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4807
Datum to_hex32(PG_FUNCTION_ARGS)
Definition: varlena.c:4993
Datum text_starts_with(PG_FUNCTION_ARGS)
Definition: varlena.c:1790
Datum byteale(PG_FUNCTION_ARGS)
Definition: varlena.c:3877
Datum text_gt(PG_FUNCTION_ARGS)
Definition: varlena.c:1760
Datum text_reverse(PG_FUNCTION_ARGS)
Definition: varlena.c:5582
Datum to_bin64(PG_FUNCTION_ARGS)
Definition: varlena.c:4962
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1618
Datum to_oct64(PG_FUNCTION_ARGS)
Definition: varlena.c:4981
Datum text_pattern_gt(PG_FUNCTION_ARGS)
Definition: varlena.c:2866
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:806
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1872
static int namefastcmp_c(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2081
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:2985
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5161
Datum textlename(PG_FUNCTION_ARGS)
Definition: varlena.c:2767
Datum icu_unicode_version(PG_FUNCTION_ARGS)
Definition: varlena.c:6301
static int namefastcmp_locale(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2124
Datum bytearecv(PG_FUNCTION_ARGS)
Definition: varlena.c:471
static Datum varstr_abbrev_convert(Datum original, SortSupport ssup)
Definition: varlena.c:2238
Datum text_concat(PG_FUNCTION_ARGS)
Definition: varlena.c:5501
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:196
Datum text_pattern_lt(PG_FUNCTION_ARGS)
Definition: varlena.c:2818
Datum text_pattern_ge(PG_FUNCTION_ARGS)
Definition: varlena.c:2850
Datum btvarstrequalimage(PG_FUNCTION_ARGS)
Definition: varlena.c:2554
Datum nameletext(PG_FUNCTION_ARGS)
Definition: varlena.c:2743
#define CmpCall(cmpfunc)
Definition: varlena.c:2730
Datum namenetext(PG_FUNCTION_ARGS)
Definition: varlena.c:2649
static int text_position_get_match_pos(TextPositionState *state)
Definition: varlena.c:1478
void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len)
Definition: varlena.c:248
Datum to_bin32(PG_FUNCTION_ARGS)
Definition: varlena.c:4955
Datum bytea_sortsupport(PG_FUNCTION_ARGS)
Definition: varlena.c:3959
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3027
Datum to_oct32(PG_FUNCTION_ARGS)
Definition: varlena.c:4974
Datum namegttext(PG_FUNCTION_ARGS)
Definition: varlena.c:2749
Datum unicode_version(PG_FUNCTION_ARGS)
Definition: varlena.c:6292
Datum namegetext(PG_FUNCTION_ARGS)
Definition: varlena.c:2755
static UnicodeNormalizationForm unicode_norm_form_from_string(const char *formstr)
Definition: varlena.c:6255
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:2952
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1335
Datum textoctetlen(PG_FUNCTION_ARGS)
Definition: varlena.c:731
Datum textltname(PG_FUNCTION_ARGS)
Definition: varlena.c:2761
Datum byteaoverlay_no_len(PG_FUNCTION_ARGS)
Definition: varlena.c:3105
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5421
text * replace_text_regexp(text *src_text, text *pattern_text, text *replace_text, int cflags, Oid collation, int search_start, int n)
Definition: varlena.c:4205
text * cstring_to_text(const char *s)
Definition: varlena.c:184
Datum bttextsortsupport(PG_FUNCTION_ARGS)
Definition: varlena.c:1845
Datum text_format_nv(PG_FUNCTION_ARGS)
Definition: varlena.c:6141
Datum textpos(PG_FUNCTION_ARGS)
Definition: varlena.c:1152
static int varstrfastcmp_c(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2011
Datum bttext_pattern_cmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2882
Datum string_agg_finalfn(PG_FUNCTION_ARGS)
Definition: varlena.c:5357
Datum byteaoctetlen(PG_FUNCTION_ARGS)
Definition: varlena.c:2921
Datum unistr(PG_FUNCTION_ARGS)
Definition: varlena.c:6501
static unsigned int hexval(unsigned char c)
Definition: varlena.c:6471
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:5914
Datum unknownin(PG_FUNCTION_ARGS)
Definition: varlena.c:634
static bool isxdigits_n(const char *instr, size_t n)
Definition: varlena.c:6461
Datum string_agg_deserialize(PG_FUNCTION_ARGS)
Definition: varlena.c:5321
Datum byteaout(PG_FUNCTION_ARGS)
Definition: varlena.c:388
Datum namelttext(PG_FUNCTION_ARGS)
Definition: varlena.c:2737
Datum pg_column_size(PG_FUNCTION_ARGS)
Definition: varlena.c:5013
Datum byteain(PG_FUNCTION_ARGS)
Definition: varlena.c:290
#define DatumGetVarStringPP(X)
Definition: varlena.c:117
Datum pg_column_compression(PG_FUNCTION_ARGS)
Definition: varlena.c:5060
Datum name_text(PG_FUNCTION_ARGS)
Definition: varlena.c:3381
Datum bytea_string_agg_transfn(PG_FUNCTION_ARGS)
Definition: varlena.c:498
Datum nameeqtext(PG_FUNCTION_ARGS)
Definition: varlena.c:2599
Datum bttextnamecmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2715
void initClosestMatch(ClosestMatchState *state, const char *source, int max_d)
Definition: varlena.c:6187
Datum textin(PG_FUNCTION_ARGS)
Definition: varlena.c:579
Datum string_agg_combine(PG_FUNCTION_ARGS)
Definition: varlena.c:5240
Datum byteaGetByte(PG_FUNCTION_ARGS)
Definition: varlena.c:3208
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2699
Datum unknownsend(PG_FUNCTION_ARGS)
Definition: varlena.c:673
Datum text_pattern_le(PG_FUNCTION_ARGS)
Definition: varlena.c:2834
#define TEXTBUFLEN
Definition: varlena.c:114
void updateClosestMatch(ClosestMatchState *state, const char *candidate)
Definition: varlena.c:6207
#define VAL(CH)
Definition: varlena.c:275
Datum bttextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:1830
Datum unknownout(PG_FUNCTION_ARGS)
Definition: varlena.c:646
Datum replace_text(PG_FUNCTION_ARGS)
Definition: varlena.c:3995
Datum textgename(PG_FUNCTION_ARGS)
Definition: varlena.c:2779
static bool split_text(FunctionCallInfo fcinfo, SplitTextOutputData *tstate)
Definition: varlena.c:4590
Datum bytea_substr(PG_FUNCTION_ARGS)
Definition: varlena.c:3004
Datum bytealt(PG_FUNCTION_ARGS)
Definition: varlena.c:3857
Datum byteasend(PG_FUNCTION_ARGS)
Definition: varlena.c:490
Datum text_lt(PG_FUNCTION_ARGS)
Definition: varlena.c:1730
int varstr_levenshtein_less_equal(const char *source, int slen, const char *target, int tlen, int ins_c, int del_c, int sub_c, int max_d, bool trusted)
unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
Definition: wchar.c:484
pg_wchar utf8_to_unicode(const unsigned char *c)
Definition: wchar.c:680