PostgreSQL Source Code  git master
varlena.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <limits.h>
#include "access/detoast.h"
#include "access/toast_compression.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "common/unicode_category.h"
#include "common/unicode_norm.h"
#include "common/unicode_version.h"
#include "funcapi.h"
#include "lib/hyperloglog.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "parser/scansup.h"
#include "port/pg_bswap.h"
#include "regex/regex.h"
#include "utils/builtins.h"
#include "utils/bytea.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/pg_locale.h"
#include "utils/sortsupport.h"
#include "utils/varlena.h"
#include "levenshtein.c"
Include dependency graph for varlena.c:

Go to the source code of this file.

Data Structures

struct  TextPositionState
 
struct  VarStringSortSupport
 
struct  SplitTextOutputData
 

Macros

#define TEXTBUFLEN   1024
 
#define DatumGetVarStringP(X)   ((VarString *) PG_DETOAST_DATUM(X))
 
#define DatumGetVarStringPP(X)   ((VarString *) PG_DETOAST_DATUM_PACKED(X))
 
#define VAL(CH)   ((CH) - '0')
 
#define DIG(VAL)   ((VAL) + '0')
 
#define CmpCall(cmpfunc)
 
#define PG_STR_GET_BYTEA(str_)    DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
 
#define TEXT_FORMAT_FLAG_MINUS   0x0001 /* is minus flag present? */
 
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
 
#define LEVENSHTEIN_LESS_EQUAL
 

Typedefs

typedef struct varlena VarString
 

Functions

static int varstrfastcmp_c (Datum x, Datum y, SortSupport ssup)
 
static int bpcharfastcmp_c (Datum x, Datum y, SortSupport ssup)
 
static int namefastcmp_c (Datum x, Datum y, SortSupport ssup)
 
static int varlenafastcmp_locale (Datum x, Datum y, SortSupport ssup)
 
static int namefastcmp_locale (Datum x, Datum y, SortSupport ssup)
 
static int varstrfastcmp_locale (char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
 
static Datum varstr_abbrev_convert (Datum original, SortSupport ssup)
 
static bool varstr_abbrev_abort (int memtupcount, SortSupport ssup)
 
static int32 text_length (Datum str)
 
static texttext_catenate (text *t1, text *t2)
 
static texttext_substring (Datum str, int32 start, int32 length, bool length_not_specified)
 
static texttext_overlay (text *t1, text *t2, int sp, int sl)
 
static int text_position (text *t1, text *t2, Oid collid)
 
static void text_position_setup (text *t1, text *t2, Oid collid, TextPositionState *state)
 
static bool text_position_next (TextPositionState *state)
 
static char * text_position_next_internal (char *start_ptr, TextPositionState *state)
 
static char * text_position_get_match_ptr (TextPositionState *state)
 
static int text_position_get_match_pos (TextPositionState *state)
 
static void text_position_cleanup (TextPositionState *state)
 
static void check_collation_set (Oid collid)
 
static int text_cmp (text *arg1, text *arg2, Oid collid)
 
static byteabytea_catenate (bytea *t1, bytea *t2)
 
static byteabytea_substring (Datum str, int S, int L, bool length_not_specified)
 
static byteabytea_overlay (bytea *t1, bytea *t2, int sp, int sl)
 
static void appendStringInfoText (StringInfo str, const text *t)
 
static bool split_text (FunctionCallInfo fcinfo, SplitTextOutputData *tstate)
 
static void split_text_accum_result (SplitTextOutputData *tstate, text *field_value, text *null_string, Oid collation)
 
static textarray_to_text_internal (FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
 
static StringInfo makeStringAggState (FunctionCallInfo fcinfo)
 
static bool text_format_parse_digits (const char **ptr, const char *end_ptr, int *value)
 
static const char * text_format_parse_format (const char *start_ptr, const char *end_ptr, int *argpos, int *widthpos, int *flags, int *width)
 
static void text_format_string_conversion (StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
 
static void text_format_append_string (StringInfo buf, const char *str, int flags, int width)
 
textcstring_to_text (const char *s)
 
textcstring_to_text_with_len (const char *s, int len)
 
char * text_to_cstring (const text *t)
 
void text_to_cstring_buffer (const text *src, char *dst, size_t dst_len)
 
Datum byteain (PG_FUNCTION_ARGS)
 
Datum byteaout (PG_FUNCTION_ARGS)
 
Datum bytearecv (PG_FUNCTION_ARGS)
 
Datum byteasend (PG_FUNCTION_ARGS)
 
Datum bytea_string_agg_transfn (PG_FUNCTION_ARGS)
 
Datum bytea_string_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum textin (PG_FUNCTION_ARGS)
 
Datum textout (PG_FUNCTION_ARGS)
 
Datum textrecv (PG_FUNCTION_ARGS)
 
Datum textsend (PG_FUNCTION_ARGS)
 
Datum unknownin (PG_FUNCTION_ARGS)
 
Datum unknownout (PG_FUNCTION_ARGS)
 
Datum unknownrecv (PG_FUNCTION_ARGS)
 
Datum unknownsend (PG_FUNCTION_ARGS)
 
Datum textlen (PG_FUNCTION_ARGS)
 
Datum textoctetlen (PG_FUNCTION_ARGS)
 
Datum textcat (PG_FUNCTION_ARGS)
 
static int charlen_to_bytelen (const char *p, int n)
 
Datum text_substr (PG_FUNCTION_ARGS)
 
Datum text_substr_no_len (PG_FUNCTION_ARGS)
 
Datum textoverlay (PG_FUNCTION_ARGS)
 
Datum textoverlay_no_len (PG_FUNCTION_ARGS)
 
Datum textpos (PG_FUNCTION_ARGS)
 
static void text_position_reset (TextPositionState *state)
 
int varstr_cmp (const char *arg1, int len1, const char *arg2, int len2, Oid collid)
 
Datum texteq (PG_FUNCTION_ARGS)
 
Datum textne (PG_FUNCTION_ARGS)
 
Datum text_lt (PG_FUNCTION_ARGS)
 
Datum text_le (PG_FUNCTION_ARGS)
 
Datum text_gt (PG_FUNCTION_ARGS)
 
Datum text_ge (PG_FUNCTION_ARGS)
 
Datum text_starts_with (PG_FUNCTION_ARGS)
 
Datum bttextcmp (PG_FUNCTION_ARGS)
 
Datum bttextsortsupport (PG_FUNCTION_ARGS)
 
void varstr_sortsupport (SortSupport ssup, Oid typid, Oid collid)
 
Datum btvarstrequalimage (PG_FUNCTION_ARGS)
 
Datum text_larger (PG_FUNCTION_ARGS)
 
Datum text_smaller (PG_FUNCTION_ARGS)
 
Datum nameeqtext (PG_FUNCTION_ARGS)
 
Datum texteqname (PG_FUNCTION_ARGS)
 
Datum namenetext (PG_FUNCTION_ARGS)
 
Datum textnename (PG_FUNCTION_ARGS)
 
Datum btnametextcmp (PG_FUNCTION_ARGS)
 
Datum bttextnamecmp (PG_FUNCTION_ARGS)
 
Datum namelttext (PG_FUNCTION_ARGS)
 
Datum nameletext (PG_FUNCTION_ARGS)
 
Datum namegttext (PG_FUNCTION_ARGS)
 
Datum namegetext (PG_FUNCTION_ARGS)
 
Datum textltname (PG_FUNCTION_ARGS)
 
Datum textlename (PG_FUNCTION_ARGS)
 
Datum textgtname (PG_FUNCTION_ARGS)
 
Datum textgename (PG_FUNCTION_ARGS)
 
static int internal_text_pattern_compare (text *arg1, text *arg2)
 
Datum text_pattern_lt (PG_FUNCTION_ARGS)
 
Datum text_pattern_le (PG_FUNCTION_ARGS)
 
Datum text_pattern_ge (PG_FUNCTION_ARGS)
 
Datum text_pattern_gt (PG_FUNCTION_ARGS)
 
Datum bttext_pattern_cmp (PG_FUNCTION_ARGS)
 
Datum bttext_pattern_sortsupport (PG_FUNCTION_ARGS)
 
Datum byteaoctetlen (PG_FUNCTION_ARGS)
 
Datum byteacat (PG_FUNCTION_ARGS)
 
Datum bytea_substr (PG_FUNCTION_ARGS)
 
Datum bytea_substr_no_len (PG_FUNCTION_ARGS)
 
Datum byteaoverlay (PG_FUNCTION_ARGS)
 
Datum byteaoverlay_no_len (PG_FUNCTION_ARGS)
 
Datum bytea_bit_count (PG_FUNCTION_ARGS)
 
Datum byteapos (PG_FUNCTION_ARGS)
 
Datum byteaGetByte (PG_FUNCTION_ARGS)
 
Datum byteaGetBit (PG_FUNCTION_ARGS)
 
Datum byteaSetByte (PG_FUNCTION_ARGS)
 
Datum byteaSetBit (PG_FUNCTION_ARGS)
 
Datum text_name (PG_FUNCTION_ARGS)
 
Datum name_text (PG_FUNCTION_ARGS)
 
ListtextToQualifiedNameList (text *textval)
 
bool SplitIdentifierString (char *rawstring, char separator, List **namelist)
 
bool SplitDirectoriesString (char *rawstring, char separator, List **namelist)
 
bool SplitGUCList (char *rawstring, char separator, List **namelist)
 
Datum byteaeq (PG_FUNCTION_ARGS)
 
Datum byteane (PG_FUNCTION_ARGS)
 
Datum bytealt (PG_FUNCTION_ARGS)
 
Datum byteale (PG_FUNCTION_ARGS)
 
Datum byteagt (PG_FUNCTION_ARGS)
 
Datum byteage (PG_FUNCTION_ARGS)
 
Datum byteacmp (PG_FUNCTION_ARGS)
 
Datum bytea_sortsupport (PG_FUNCTION_ARGS)
 
Datum replace_text (PG_FUNCTION_ARGS)
 
static int check_replace_text_has_escape (const text *replace_text)
 
static void appendStringInfoRegexpSubstr (StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
 
textreplace_text_regexp (text *src_text, text *pattern_text, text *replace_text, int cflags, Oid collation, int search_start, int n)
 
Datum split_part (PG_FUNCTION_ARGS)
 
static bool text_isequal (text *txt1, text *txt2, Oid collid)
 
Datum text_to_array (PG_FUNCTION_ARGS)
 
Datum text_to_array_null (PG_FUNCTION_ARGS)
 
Datum text_to_table (PG_FUNCTION_ARGS)
 
Datum text_to_table_null (PG_FUNCTION_ARGS)
 
Datum array_to_text (PG_FUNCTION_ARGS)
 
Datum array_to_text_null (PG_FUNCTION_ARGS)
 
static textconvert_to_base (uint64 value, int base)
 
Datum to_bin32 (PG_FUNCTION_ARGS)
 
Datum to_bin64 (PG_FUNCTION_ARGS)
 
Datum to_oct32 (PG_FUNCTION_ARGS)
 
Datum to_oct64 (PG_FUNCTION_ARGS)
 
Datum to_hex32 (PG_FUNCTION_ARGS)
 
Datum to_hex64 (PG_FUNCTION_ARGS)
 
Datum pg_column_size (PG_FUNCTION_ARGS)
 
Datum pg_column_compression (PG_FUNCTION_ARGS)
 
Datum string_agg_transfn (PG_FUNCTION_ARGS)
 
Datum string_agg_combine (PG_FUNCTION_ARGS)
 
Datum string_agg_serialize (PG_FUNCTION_ARGS)
 
Datum string_agg_deserialize (PG_FUNCTION_ARGS)
 
Datum string_agg_finalfn (PG_FUNCTION_ARGS)
 
static FmgrInfobuild_concat_foutcache (FunctionCallInfo fcinfo, int argidx)
 
static textconcat_internal (const char *sepstr, int argidx, FunctionCallInfo fcinfo)
 
Datum text_concat (PG_FUNCTION_ARGS)
 
Datum text_concat_ws (PG_FUNCTION_ARGS)
 
Datum text_left (PG_FUNCTION_ARGS)
 
Datum text_right (PG_FUNCTION_ARGS)
 
Datum text_reverse (PG_FUNCTION_ARGS)
 
Datum text_format (PG_FUNCTION_ARGS)
 
Datum text_format_nv (PG_FUNCTION_ARGS)
 
static bool rest_of_char_same (const char *s1, const char *s2, int len)
 
void initClosestMatch (ClosestMatchState *state, const char *source, int max_d)
 
void updateClosestMatch (ClosestMatchState *state, const char *candidate)
 
const char * getClosestMatch (ClosestMatchState *state)
 
static UnicodeNormalizationForm unicode_norm_form_from_string (const char *formstr)
 
Datum unicode_version (PG_FUNCTION_ARGS)
 
Datum icu_unicode_version (PG_FUNCTION_ARGS)
 
Datum unicode_assigned (PG_FUNCTION_ARGS)
 
Datum unicode_normalize_func (PG_FUNCTION_ARGS)
 
Datum unicode_is_normalized (PG_FUNCTION_ARGS)
 
static bool isxdigits_n (const char *instr, size_t n)
 
static unsigned int hexval (unsigned char c)
 
static unsigned int hexval_n (const char *instr, size_t n)
 
Datum unistr (PG_FUNCTION_ARGS)
 

Variables

int bytea_output = BYTEA_OUTPUT_HEX
 

Macro Definition Documentation

◆ ADVANCE_PARSE_POINTER

#define ADVANCE_PARSE_POINTER (   ptr,
  end_ptr 
)
Value:
do { \
if (++(ptr) >= (end_ptr)) \
ereport(ERROR, \
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
errmsg("unterminated format() type specifier"), \
errhint("For a single \"%%\" use \"%%%%\"."))); \
} while (0)
int errhint(const char *fmt,...)
Definition: elog.c:1320
int errcode(int sqlerrcode)
Definition: elog.c:860
int errmsg(const char *fmt,...)
Definition: elog.c:1073
#define ERROR
Definition: elog.h:39

Definition at line 5583 of file varlena.c.

◆ CmpCall

#define CmpCall (   cmpfunc)
Value:
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:812
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GET_COLLATION()
Definition: fmgr.h:198
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:202

Definition at line 2730 of file varlena.c.

◆ DatumGetVarStringP

#define DatumGetVarStringP (   X)    ((VarString *) PG_DETOAST_DATUM(X))

Definition at line 116 of file varlena.c.

◆ DatumGetVarStringPP

#define DatumGetVarStringPP (   X)    ((VarString *) PG_DETOAST_DATUM_PACKED(X))

Definition at line 117 of file varlena.c.

◆ DIG

#define DIG (   VAL)    ((VAL) + '0')

Definition at line 276 of file varlena.c.

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

Definition at line 6123 of file varlena.c.

◆ PG_STR_GET_BYTEA

#define PG_STR_GET_BYTEA (   str_)     DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))

Definition at line 2985 of file varlena.c.

◆ TEXT_FORMAT_FLAG_MINUS

#define TEXT_FORMAT_FLAG_MINUS   0x0001 /* is minus flag present? */

Definition at line 5581 of file varlena.c.

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 114 of file varlena.c.

◆ VAL

#define VAL (   CH)    ((CH) - '0')

Definition at line 275 of file varlena.c.

Typedef Documentation

◆ VarString

typedef struct varlena VarString

Definition at line 48 of file varlena.c.

Function Documentation

◆ appendStringInfoRegexpSubstr()

static void appendStringInfoRegexpSubstr ( StringInfo  str,
text replace_text,
regmatch_t pmatch,
char *  start_ptr,
int  data_pos 
)
static

Definition at line 4105 of file varlena.c.

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 }
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
Assert(fmt[strlen(fmt) - 1] !='\n')
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:233
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
regoff_t rm_eo
Definition: regex.h:86
regoff_t rm_so
Definition: regex.h:85
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:806
Datum replace_text(PG_FUNCTION_ARGS)
Definition: varlena.c:3995

References appendBinaryStringInfo(), appendStringInfoChar(), Assert(), charlen_to_bytelen(), idx(), replace_text(), regmatch_t::rm_eo, regmatch_t::rm_so, generate_unaccent_rules::str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text_regexp().

◆ appendStringInfoText()

static void appendStringInfoText ( StringInfo  str,
const text t 
)
static

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

Definition at line 4765 of file varlena.c.

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 }
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
char * text_to_cstring(const text *t)
Definition: varlena.c:217
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4807

References array_to_text_internal(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, and text_to_cstring().

◆ array_to_text_internal()

static text * array_to_text_internal ( FunctionCallInfo  fcinfo,
ArrayType v,
const char *  fldsep,
const char *  null_string 
)
static

Definition at line 4807 of file varlena.c.

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 }
#define ARR_NDIM(a)
Definition: array.h:290
#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 ARR_DIMS(a)
Definition: array.h:294
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
uint8 bits8
Definition: c.h:500
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
#define nitems(x)
Definition: indent.h:31
static struct @149 value
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
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:2280
@ IOFunc_output
Definition: lsyscache.h:36
void pfree(void *pointer)
Definition: mcxt.c:1405
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1066
static char * buf
Definition: pg_test_fsync.c:73
char typalign
Definition: pg_type.h:176
uintptr_t Datum
Definition: postgres.h:64
unsigned int Oid
Definition: postgres_ext.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:182
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
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
void * fn_extra
Definition: fmgr.h:64
MemoryContext fn_mcxt
Definition: fmgr.h:65
FmgrInfo * flinfo
Definition: fmgr.h:87
Definition: c.h:674
#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
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:196

References appendStringInfo(), appendStringInfoString(), ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_NDIM, ARR_NULLBITMAP, ArrayGetNItems(), att_addlength_pointer, att_align_nominal, buf, cstring_to_text_with_len(), ArrayMetaState::element_type, fetch_att(), FunctionCallInfoBaseData::flinfo, fmgr_info_cxt(), FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, get_type_io_data(), i, if(), initStringInfo(), IOFunc_output, MemoryContextAlloc(), nitems, OutputFunctionCall(), pfree(), ArrayMetaState::proc, typalign, ArrayMetaState::typalign, ArrayMetaState::typbyval, ArrayMetaState::typdelim, ArrayMetaState::typiofunc, ArrayMetaState::typioparam, ArrayMetaState::typlen, and value.

Referenced by array_to_text(), array_to_text_null(), and concat_internal().

◆ array_to_text_null()

Datum array_to_text_null ( PG_FUNCTION_ARGS  )

Definition at line 4781 of file varlena.c.

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 }
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345

References array_to_text_internal(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_TEXT_P, and text_to_cstring().

◆ bpcharfastcmp_c()

static int bpcharfastcmp_c ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 2048 of file varlena.c.

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 }
#define Min(x, y)
Definition: c.h:991
#define DatumGetBpCharPP(X)
Definition: fmgr.h:293
int y
Definition: isn.c:72
int x
Definition: isn.c:71
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
int bpchartruelen(char *s, int len)
Definition: varchar.c:677

References bpchartruelen(), DatumGetBpCharPP, Min, pfree(), PointerGetDatum(), VARDATA_ANY, VARSIZE_ANY_EXHDR, x, and y.

Referenced by varstr_sortsupport().

◆ btnametextcmp()

Datum btnametextcmp ( PG_FUNCTION_ARGS  )

Definition at line 2699 of file varlena.c.

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 }
#define NameStr(name)
Definition: c.h:733
signed int int32
Definition: c.h:481
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
Definition: c.h:728
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1538

References NameStr, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_INT32, VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

Referenced by namegetext(), namegttext(), nameletext(), and namelttext().

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2882 of file varlena.c.

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 }
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2796

References internal_text_pattern_compare(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, and PG_RETURN_INT32.

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2898 of file varlena.c.

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 }
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1872

References MemoryContextSwitchTo(), PG_GETARG_POINTER, PG_RETURN_VOID, SortSupportData::ssup_cxt, and varstr_sortsupport().

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

Definition at line 1830 of file varlena.c.

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 }
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1593

References PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_INT32, and text_cmp().

Referenced by gbt_textcmp().

◆ bttextnamecmp()

Datum bttextnamecmp ( PG_FUNCTION_ARGS  )

Definition at line 2715 of file varlena.c.

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 }

References NameStr, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_INT32, VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

Referenced by textgename(), textgtname(), textlename(), and textltname().

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1845 of file varlena.c.

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 }
Oid collid

References collid, MemoryContextSwitchTo(), PG_GETARG_POINTER, PG_RETURN_VOID, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, and varstr_sortsupport().

◆ btvarstrequalimage()

Datum btvarstrequalimage ( PG_FUNCTION_ARGS  )

Definition at line 2554 of file varlena.c.

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 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:1053
bool lc_collate_is_c(Oid collation)
Definition: pg_locale.c:1307
static void check_collation_set(Oid collid)
Definition: varlena.c:1509

References check_collation_set(), collid, get_collation_isdeterministic(), lc_collate_is_c(), PG_GET_COLLATION, and PG_RETURN_BOOL.

◆ build_concat_foutcache()

static FmgrInfo* build_concat_foutcache ( FunctionCallInfo  fcinfo,
int  argidx 
)
static

Definition at line 5342 of file varlena.c.

5343 {
5344  FmgrInfo *foutcache;
5345  int i;
5346 
5347  /* We keep the info in fn_mcxt so it survives across calls */
5348  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5349  PG_NARGS() * sizeof(FmgrInfo));
5350 
5351  for (i = argidx; i < PG_NARGS(); i++)
5352  {
5353  Oid valtype;
5354  Oid typOutput;
5355  bool typIsVarlena;
5356 
5357  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5358  if (!OidIsValid(valtype))
5359  elog(ERROR, "could not determine data type of concat() input");
5360 
5361  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5362  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5363  }
5364 
5365  fcinfo->flinfo->fn_extra = foutcache;
5366 
5367  return foutcache;
5368 }
#define OidIsValid(objectId)
Definition: c.h:762
#define elog(elevel,...)
Definition: elog.h:224
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1910
struct FmgrInfo FmgrInfo
#define PG_NARGS()
Definition: fmgr.h:203
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2862
Definition: fmgr.h:57

References elog, ERROR, FunctionCallInfoBaseData::flinfo, fmgr_info_cxt(), FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, get_fn_expr_argtype(), getTypeOutputInfo(), i, MemoryContextAlloc(), OidIsValid, and PG_NARGS.

Referenced by concat_internal().

◆ bytea_bit_count()

Datum bytea_bit_count ( PG_FUNCTION_ARGS  )

Definition at line 3150 of file varlena.c.

3151 {
3152  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3153 
3155 }
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:296

References PG_GETARG_BYTEA_PP, pg_popcount(), PG_RETURN_INT64, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_catenate()

static bytea * bytea_catenate ( bytea t1,
bytea t2 
)
static

Definition at line 2952 of file varlena.c.

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 }
#define VARHDRSZ
Definition: c.h:679
void * palloc(Size size)
Definition: mcxt.c:1201
const void size_t len
#define VARDATA(PTR)
Definition: varatt.h:278
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References len, palloc(), SET_VARSIZE, VARDATA, VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

Referenced by bytea_overlay(), and byteacat().

◆ bytea_overlay()

static bytea * bytea_overlay ( bytea t1,
bytea t2,
int  sp,
int  sl 
)
static

Definition at line 3117 of file varlena.c.

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 }
#define ereport(elevel,...)
Definition: elog.h:149
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
char * s1
char * s2
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3027
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:2952

References bytea_catenate(), bytea_substring(), ereport, errcode(), errmsg(), ERROR, pg_add_s32_overflow(), PointerGetDatum(), s1, and s2.

Referenced by byteaoverlay(), and byteaoverlay_no_len().

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 3959 of file varlena.c.

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 }

References MemoryContextSwitchTo(), PG_GETARG_POINTER, PG_RETURN_VOID, SortSupportData::ssup_cxt, and varstr_sortsupport().

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 551 of file varlena.c.

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 }
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4512
StringInfoData * StringInfo
Definition: stringinfo.h:54
Definition: regguts.h:323

References AggCheckCallContext(), Assert(), palloc(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_BYTEA_P, PG_RETURN_NULL, SET_VARSIZE, VARDATA, and VARHDRSZ.

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 498 of file varlena.c.

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 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5120

References appendBinaryStringInfo(), makeStringAggState(), PG_ARGISNULL, PG_GETARG_BYTEA_PP, PG_GETARG_POINTER, PG_RETURN_NULL, PG_RETURN_POINTER, value, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 3004 of file varlena.c.

3005 {
3007  PG_GETARG_INT32(1),
3008  PG_GETARG_INT32(2),
3009  false));
3010 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269

References bytea_substring(), PG_GETARG_DATUM, PG_GETARG_INT32, and PG_RETURN_BYTEA_P.

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3018 of file varlena.c.

3019 {
3021  PG_GETARG_INT32(1),
3022  -1,
3023  true));
3024 }

References bytea_substring(), PG_GETARG_DATUM, PG_GETARG_INT32, and PG_RETURN_BYTEA_P.

◆ bytea_substring()

static bytea * bytea_substring ( Datum  str,
int  S,
int  L,
bool  length_not_specified 
)
static

Definition at line 3027 of file varlena.c.

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 }
#define Max(x, y)
Definition: c.h:985
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:303
#define S(n, x)
Definition: sha1.c:73
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:2985

References DatumGetByteaPSlice, ereport, errcode(), errmsg(), ERROR, Max, pg_add_s32_overflow(), PG_STR_GET_BYTEA, S, and generate_unaccent_rules::str.

Referenced by bytea_overlay(), bytea_substr(), and bytea_substr_no_len().

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 2937 of file varlena.c.

2938 {
2939  bytea *t1 = PG_GETARG_BYTEA_PP(0);
2940  bytea *t2 = PG_GETARG_BYTEA_PP(1);
2941 
2943 }

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

Definition at line 3937 of file varlena.c.

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 }
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743

References cmp(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_INT32, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by gbt_bitcmp(), and gbt_byteacmp().

◆ byteaeq()

Datum byteaeq ( PG_FUNCTION_ARGS  )

Definition at line 3793 of file varlena.c.

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 }
size_t Size
Definition: c.h:592
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
#define DatumGetByteaPP(X)
Definition: fmgr.h:291

References DatumGetByteaPP, PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_RETURN_BOOL, toast_raw_datum_size(), VARDATA_ANY, and VARHDRSZ.

Referenced by gbt_byteaeq().

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

Definition at line 3917 of file varlena.c.

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 }

References cmp(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by gbt_byteage().

◆ byteaGetBit()

Datum byteaGetBit ( PG_FUNCTION_ARGS  )

Definition at line 3237 of file varlena.c.

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 }
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

References ereport, errcode(), errmsg(), ERROR, len, PG_GETARG_BYTEA_PP, PG_GETARG_INT64, PG_RETURN_INT32, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

Definition at line 3208 of file varlena.c.

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 }

References ereport, errcode(), errmsg(), ERROR, len, PG_GETARG_BYTEA_PP, PG_GETARG_INT32, PG_RETURN_INT32, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

Definition at line 3897 of file varlena.c.

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 }

References cmp(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by gbt_byteagt().

◆ byteain()

Datum byteain ( PG_FUNCTION_ARGS  )

Definition at line 290 of file varlena.c.

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 }
#define ereturn(context, dummy_value,...)
Definition: elog.h:276
uint64 hex_decode_safe(const char *src, size_t len, char *dst, Node *escontext)
Definition: encode.c:196
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
Definition: nodes.h:129
#define VAL(CH)
Definition: varlena.c:275

References ereturn, errcode(), errmsg(), hex_decode_safe(), len, palloc(), PG_GETARG_CSTRING, PG_RETURN_BYTEA_P, SET_VARSIZE, VAL, VARDATA, and VARHDRSZ.

Referenced by CreateTriggerFiringOn(), and string_to_datum().

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

Definition at line 3877 of file varlena.c.

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 }

References cmp(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by gbt_byteale().

◆ bytealt()

Datum bytealt ( PG_FUNCTION_ARGS  )

Definition at line 3857 of file varlena.c.

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 }

References cmp(), Min, PG_FREE_IF_COPY, PG_GETARG_BYTEA_PP, PG_RETURN_BOOL, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by gbt_bytealt().

◆ byteane()

Datum byteane ( PG_FUNCTION_ARGS  )

Definition at line 3825 of file varlena.c.

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 }

References DatumGetByteaPP, PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_RETURN_BOOL, toast_raw_datum_size(), VARDATA_ANY, and VARHDRSZ.

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 2921 of file varlena.c.

2922 {
2923  Datum str = PG_GETARG_DATUM(0);
2924 
2925  /* We need not detoast the input at all */
2927 }

References PG_GETARG_DATUM, PG_RETURN_INT32, generate_unaccent_rules::str, toast_raw_datum_size(), and VARHDRSZ.

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 388 of file varlena.c.

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 }
@ BYTEA_OUTPUT_HEX
Definition: bytea.h:22
@ BYTEA_OUTPUT_ESCAPE
Definition: bytea.h:21
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1160
uint64 hex_encode(const char *src, size_t len, char *dst)
Definition: encode.c:162
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
long val
Definition: informix.c:664
#define MaxAllocSize
Definition: memutils.h:40
int bytea_output
Definition: varlena.c:48
#define DIG(VAL)
Definition: varlena.c:276

References bytea_output, BYTEA_OUTPUT_ESCAPE, BYTEA_OUTPUT_HEX, DIG, elog, ereport, errcode(), errmsg_internal(), ERROR, hex_encode(), i, len, MaxAllocSize, palloc(), PG_GETARG_BYTEA_PP, PG_RETURN_CSTRING, val, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by pg_mcv_list_out().

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 3094 of file varlena.c.

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 }
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3117

References bytea_overlay(), PG_GETARG_BYTEA_PP, PG_GETARG_INT32, and PG_RETURN_BYTEA_P.

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3105 of file varlena.c.

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 }

References bytea_overlay(), PG_GETARG_BYTEA_PP, PG_GETARG_INT32, PG_RETURN_BYTEA_P, and VARSIZE_ANY_EXHDR.

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 3164 of file varlena.c.

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 }
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)

References p2, PG_GETARG_BYTEA_PP, PG_RETURN_INT32, px(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

Definition at line 471 of file varlena.c.

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 }
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:531

References buf, palloc(), PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_copymsgbytes(), SET_VARSIZE, VARDATA, and VARHDRSZ.

◆ byteasend()

Datum byteasend ( PG_FUNCTION_ARGS  )

Definition at line 490 of file varlena.c.

491 {
492  bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
493 
494  PG_RETURN_BYTEA_P(vlena);
495 }
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314

References PG_GETARG_BYTEA_P_COPY, and PG_RETURN_BYTEA_P.

Referenced by brin_bloom_summary_send(), brin_minmax_multi_summary_send(), pg_dependencies_send(), pg_mcv_list_send(), and pg_ndistinct_send().

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 3307 of file varlena.c.

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 }
#define VARSIZE(PTR)
Definition: varatt.h:279

References ereport, errcode(), errmsg(), ERROR, len, PG_GETARG_BYTEA_P_COPY, PG_GETARG_INT32, PG_GETARG_INT64, PG_RETURN_BYTEA_P, res, VARDATA, VARHDRSZ, and VARSIZE.

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

Definition at line 3275 of file varlena.c.

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 }

References ereport, errcode(), errmsg(), ERROR, len, PG_GETARG_BYTEA_P_COPY, PG_GETARG_INT32, PG_RETURN_BYTEA_P, res, VARDATA, VARHDRSZ, and VARSIZE.

◆ charlen_to_bytelen()

static int charlen_to_bytelen ( const char *  p,
int  n 
)
static

Definition at line 806 of file varlena.c.

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 }
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1547
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1024

References pg_database_encoding_max_length(), and pg_mblen().

Referenced by appendStringInfoRegexpSubstr(), and replace_text_regexp().

◆ check_collation_set()

static void check_collation_set ( Oid  collid)
static

Definition at line 1509 of file varlena.c.

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 }

References collid, ereport, errcode(), errhint(), errmsg(), ERROR, and OidIsValid.

Referenced by btvarstrequalimage(), nameeqtext(), namenetext(), text_position_setup(), text_starts_with(), texteq(), texteqname(), textne(), textnename(), varstr_cmp(), and varstr_sortsupport().

◆ check_replace_text_has_escape()

static int check_replace_text_has_escape ( const text replace_text)
static

Definition at line 4072 of file varlena.c.

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 }

References replace_text(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text_regexp().

◆ concat_internal()

static text* concat_internal ( const char *  sepstr,
int  argidx,
FunctionCallInfo  fcinfo 
)
static

Definition at line 5380 of file varlena.c.

5382 {
5383  text *result;
5385  FmgrInfo *foutcache;
5386  bool first_arg = true;
5387  int i;
5388 
5389  /*
5390  * concat(VARIADIC some-array) is essentially equivalent to
5391  * array_to_text(), ie concat the array elements with the given separator.
5392  * So we just pass the case off to that code.
5393  */
5394  if (get_fn_expr_variadic(fcinfo->flinfo))
5395  {
5396  ArrayType *arr;
5397 
5398  /* Should have just the one argument */
5399  Assert(argidx == PG_NARGS() - 1);
5400 
5401  /* concat(VARIADIC NULL) is defined as NULL */
5402  if (PG_ARGISNULL(argidx))
5403  return NULL;
5404 
5405  /*
5406  * Non-null argument had better be an array. We assume that any call
5407  * context that could let get_fn_expr_variadic return true will have
5408  * checked that a VARIADIC-labeled parameter actually is an array. So
5409  * it should be okay to just Assert that it's an array rather than
5410  * doing a full-fledged error check.
5411  */
5413 
5414  /* OK, safe to fetch the array value */
5415  arr = PG_GETARG_ARRAYTYPE_P(argidx);
5416 
5417  /*
5418  * And serialize the array. We tell array_to_text to ignore null
5419  * elements, which matches the behavior of the loop below.
5420  */
5421  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5422  }
5423 
5424  /* Normal case without explicit VARIADIC marker */
5425  initStringInfo(&str);
5426 
5427  /* Get output function info, building it if first time through */
5428  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5429  if (foutcache == NULL)
5430  foutcache = build_concat_foutcache(fcinfo, argidx);
5431 
5432  for (i = argidx; i < PG_NARGS(); i++)
5433  {
5434  if (!PG_ARGISNULL(i))
5435  {
5437 
5438  /* add separator if appropriate */
5439  if (first_arg)
5440  first_arg = false;
5441  else
5442  appendStringInfoString(&str, sepstr);
5443 
5444  /* call the appropriate type output function, append the result */
5446  OutputFunctionCall(&foutcache[i], value));
5447  }
5448  }
5449 
5450  result = cstring_to_text_with_len(str.data, str.len);
5451  pfree(str.data);
5452 
5453  return result;
5454 }
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2044
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2787
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5342

References appendStringInfoString(), array_to_text_internal(), Assert(), build_concat_foutcache(), cstring_to_text_with_len(), FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, get_base_element_type(), get_fn_expr_argtype(), get_fn_expr_variadic(), i, if(), initStringInfo(), OidIsValid, OutputFunctionCall(), pfree(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_NARGS, generate_unaccent_rules::str, and value.

Referenced by text_concat(), and text_concat_ws().

◆ convert_to_base()

static text* convert_to_base ( uint64  value,
int  base 
)
inlinestatic

Definition at line 4929 of file varlena.c.

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 }
int digits
Definition: informix.c:666
#define BITS_PER_BYTE

References Assert(), BITS_PER_BYTE, buf, cstring_to_text_with_len(), digits, and value.

Referenced by to_bin32(), to_bin64(), to_hex32(), to_hex64(), to_oct32(), and to_oct64().

◆ cstring_to_text()

text* cstring_to_text ( const char *  s)

Definition at line 184 of file varlena.c.

185 {
186  return cstring_to_text_with_len(s, strlen(s));
187 }

References cstring_to_text_with_len().

Referenced by array_dims(), ASN1_STRING_to_text(), booltext(), brin_minmax_multi_summary_out(), brin_page_type(), build_test_info_result(), build_test_match_result(), cash_words(), cidr_abbrev(), convert_charset(), cstring_to_xmltype(), current_query(), datetime_to_char_body(), dblink_build_sql_delete(), dblink_build_sql_insert(), dblink_build_sql_update(), dblink_cancel_query(), dblink_close(), dblink_connect(), dblink_disconnect(), dblink_error_message(), dblink_exec(), dblink_open(), dmetaphone(), dmetaphone_alt(), exec_assign_c_string(), executeDateTimeMethod(), filter_list_to_array(), format_type(), get_command_tag(), get_command_type(), get_scalar(), hash_page_type(), icu_unicode_version(), inet_abbrev(), initcap(), json_in(), json_typeof(), jsonb_get_element(), jsonb_typeof(), JsonbValueAsText(), lower(), md5_bytea(), md5_text(), metaphone(), name_bpchar(), name_text(), network_host(), network_show(), oidvectortypes(), ParameterAclCreate(), ParameterAclLookup(), pg_collation_actual_version(), pg_collation_for(), pg_column_compression(), pg_crypt(), pg_current_logfile(), pg_database_collation_actual_version(), pg_describe_object(), pg_export_snapshot(), pg_get_statisticsobjdef_expressions(), pg_get_wal_replay_pause_state(), pg_parameter_aclmask(), pg_relation_filepath(), pg_size_pretty(), pg_size_pretty_numeric(), pg_stat_get_backend_activity(), pg_stat_get_backend_wait_event(), pg_stat_get_backend_wait_event_type(), pg_stat_get_slru(), pg_stats_ext_mcvlist_items(), pg_tablespace_location(), pg_walfile_name(), pg_xact_status(), pgsql_version(), pgxml_result_to_text(), quote_ident(), quote_ident_cstr(), quote_nullable(), sepgsql_getcon(), sepgsql_mcstrans_in(), sepgsql_mcstrans_out(), set_config_by_name(), show_all_file_settings(), show_config_by_name(), show_config_by_name_missing_ok(), ShowAllGUCConfig(), soundex(), split_part(), ssl_cipher(), ssl_client_dn(), ssl_issuer_dn(), ssl_version(), string_to_text(), test_canonicalize_path(), test_slru_page_read(), test_slru_page_readonly(), text_substring(), textin(), timeofday(), timetz_at_local(), tsquerytree(), unaccent_dict(), unicode_version(), upper(), xml_encode_special_chars(), xml_in(), and xml_recv().

◆ cstring_to_text_with_len()

text* cstring_to_text_with_len ( const char *  s,
int  len 
)

Definition at line 196 of file varlena.c.

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 }

References len, palloc(), SET_VARSIZE, VARDATA, and VARHDRSZ.

Referenced by array_to_json(), array_to_json_pretty(), array_to_text_internal(), brin_minmax_multi_summary_out(), build_regexp_match_result(), build_regexp_split_result(), build_test_match_result(), compute_tsvector_stats(), concat_internal(), convert_to_base(), cstring_to_text(), daitch_mokotoff_coding(), datum_to_json(), do_text_output_multiline(), dotrim(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), ExecEvalXmlExpr(), executeDateTimeMethod(), executeLikeRegex(), find_or_create_child_node(), fsm_page_contents(), get_array_element_end(), get_array_end(), get_object_end(), get_object_field_end(), get_scalar(), gin_extract_tsquery(), gin_extract_tsvector(), hstore_akeys(), hstore_avals(), hstore_each(), hstore_fetchval(), hstore_skeys(), hstore_slice_to_array(), hstore_subscript_fetch(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), json_build_array_noargs(), json_build_array_worker(), json_build_object_noargs(), json_build_object_worker(), json_object(), json_object_two_arg(), json_recv(), json_strip_nulls(), jsonb_pretty(), JsonbValueAsText(), leftmostvalue_text(), LogicalOutputWrite(), parse_ident(), pg_gen_salt(), pg_gen_salt_rounds(), pg_get_function_sqlbody(), replace_text(), replace_text_regexp(), row_to_json(), row_to_json_pretty(), serialize_deflist(), split_part(), split_text(), ssl_extension_info(), string_agg_finalfn(), stringinfo_to_xmltype(), text_format(), text_left(), text_right(), textrecv(), transform_json_string_values(), tsquerytree(), tsvector_to_array(), tsvector_unnest(), unistr(), varchar(), varchar_input(), xmltext(), and xslt_process().

◆ getClosestMatch()

const char* getClosestMatch ( ClosestMatchState state)

Definition at line 6201 of file varlena.c.

6202 {
6203  Assert(state);
6204 
6205  return state->match;
6206 }

References Assert().

Referenced by dblink_fdw_validator(), file_fdw_validator(), postgres_fdw_validator(), and postgresql_fdw_validator().

◆ hexval()

static unsigned int hexval ( unsigned char  c)
static

Definition at line 6430 of file varlena.c.

6431 {
6432  if (c >= '0' && c <= '9')
6433  return c - '0';
6434  if (c >= 'a' && c <= 'f')
6435  return c - 'a' + 0xA;
6436  if (c >= 'A' && c <= 'F')
6437  return c - 'A' + 0xA;
6438  elog(ERROR, "invalid hexadecimal digit");
6439  return 0; /* not reached */
6440 }
char * c

References elog, and ERROR.

Referenced by hexval_n().

◆ hexval_n()

static unsigned int hexval_n ( const char *  instr,
size_t  n 
)
static

Definition at line 6446 of file varlena.c.

6447 {
6448  unsigned int result = 0;
6449 
6450  for (size_t i = 0; i < n; i++)
6451  result += hexval(instr[i]) << (4 * (n - i - 1));
6452 
6453  return result;
6454 }
static unsigned int hexval(unsigned char c)
Definition: varlena.c:6430

References hexval(), and i.

Referenced by unistr().

◆ icu_unicode_version()

Datum icu_unicode_version ( PG_FUNCTION_ARGS  )

Definition at line 6260 of file varlena.c.

6261 {
6262 #ifdef USE_ICU
6263  PG_RETURN_TEXT_P(cstring_to_text(U_UNICODE_VERSION));
6264 #else
6265  PG_RETURN_NULL();
6266 #endif
6267 }
text * cstring_to_text(const char *s)
Definition: varlena.c:184

References cstring_to_text(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

Referenced by main().

◆ initClosestMatch()

void initClosestMatch ( ClosestMatchState state,
const char *  source,
int  max_d 
)

Definition at line 6146 of file varlena.c.

6147 {
6148  Assert(state);
6149  Assert(max_d >= 0);
6150 
6151  state->source = source;
6152  state->min_d = -1;
6153  state->max_d = max_d;
6154  state->match = NULL;
6155 }
static rewind_source * source
Definition: pg_rewind.c:89

References Assert(), and source.

Referenced by dblink_fdw_validator(), file_fdw_validator(), postgres_fdw_validator(), and postgresql_fdw_validator().

◆ internal_text_pattern_compare()

static int internal_text_pattern_compare ( text arg1,
text arg2 
)
static

Definition at line 2796 of file varlena.c.

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 }

References Min, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by bttext_pattern_cmp(), text_pattern_ge(), text_pattern_gt(), text_pattern_le(), and text_pattern_lt().

◆ isxdigits_n()

static bool isxdigits_n ( const char *  instr,
size_t  n 
)
static

Definition at line 6420 of file varlena.c.

6421 {
6422  for (size_t i = 0; i < n; i++)
6423  if (!isxdigit((unsigned char) instr[i]))
6424  return false;
6425 
6426  return true;
6427 }

References i.

Referenced by unistr().

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5120 of file varlena.c.

5121 {
5122  StringInfo state;
5123  MemoryContext aggcontext;
5124  MemoryContext oldcontext;
5125 
5126  if (!AggCheckCallContext(fcinfo, &aggcontext))
5127  {
5128  /* cannot be called directly because of internal-type argument */
5129  elog(ERROR, "string_agg_transfn called in non-aggregate context");
5130  }
5131 
5132  /*
5133  * Create state in aggregate context. It'll stay there across subsequent
5134  * calls.
5135  */
5136  oldcontext = MemoryContextSwitchTo(aggcontext);
5137  state = makeStringInfo();
5138  MemoryContextSwitchTo(oldcontext);
5139 
5140  return state;
5141 }
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41

References AggCheckCallContext(), elog, ERROR, makeStringInfo(), and MemoryContextSwitchTo().

Referenced by bytea_string_agg_transfn(), string_agg_combine(), string_agg_deserialize(), and string_agg_transfn().

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3381 of file varlena.c.

3382 {
3383  Name s = PG_GETARG_NAME(0);
3384 
3386 }

References cstring_to_text(), NameStr, PG_GETARG_NAME, and PG_RETURN_TEXT_P.

Referenced by nameiclike(), and nameicnlike().

◆ nameeqtext()

Datum nameeqtext ( PG_FUNCTION_ARGS  )

Definition at line 2599 of file varlena.c.

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 }

References check_collation_set(), collid, NameStr, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

◆ namefastcmp_c()

static int namefastcmp_c ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 2081 of file varlena.c.

2082 {
2083  Name arg1 = DatumGetName(x);
2084  Name arg2 = DatumGetName(y);
2085 
2086  return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2087 }
#define NAMEDATALEN
static Name DatumGetName(Datum X)
Definition: postgres.h:360

References DatumGetName(), NAMEDATALEN, NameStr, x, and y.

Referenced by varstr_sortsupport().

◆ namefastcmp_locale()

static int namefastcmp_locale ( Datum  x,
Datum  y,
SortSupport  ssup 
)
static

Definition at line 2124 of file varlena.c.

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 }
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2138

References DatumGetName(), NameStr, varstrfastcmp_locale(), x, and y.

Referenced by varstr_sortsupport().

◆ namegetext()

Datum namegetext ( PG_FUNCTION_ARGS  )

Definition at line 2755 of file varlena.c.

2756 {
2758 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2730
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2699

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ namegttext()

Datum namegttext ( PG_FUNCTION_ARGS  )

Definition at line 2749 of file varlena.c.

2750 {
2752 }

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ nameletext()

Datum nameletext ( PG_FUNCTION_ARGS  )

Definition at line 2743 of file varlena.c.

2744 {
2746 }

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ namelttext()

Datum namelttext ( PG_FUNCTION_ARGS  )

Definition at line 2737 of file varlena.c.

2738 {
2740 }

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ namenetext()

Datum namenetext ( PG_FUNCTION_ARGS  )

Definition at line 2649 of file varlena.c.

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 }

References check_collation_set(), collid, NameStr, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

◆ pg_column_compression()

Datum pg_column_compression ( PG_FUNCTION_ARGS  )

Definition at line 5060 of file varlena.c.

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 }
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2152
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
ToastCompressionId toast_get_compression_id(struct varlena *attr)
ToastCompressionId
@ TOAST_INVALID_COMPRESSION_ID
@ TOAST_LZ4_COMPRESSION_ID
@ TOAST_PGLZ_COMPRESSION_ID

References cstring_to_text(), DatumGetPointer(), elog, ERROR, get_fn_expr_argtype(), get_typlen(), MemoryContextAlloc(), PG_GETARG_DATUM, PG_RETURN_NULL, PG_RETURN_TEXT_P, toast_get_compression_id(), TOAST_INVALID_COMPRESSION_ID, TOAST_LZ4_COMPRESSION_ID, and TOAST_PGLZ_COMPRESSION_ID.

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

Definition at line 5013 of file varlena.c.

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 }
Size toast_datum_size(Datum value)
Definition: detoast.c:601
static char * DatumGetCString(Datum X)
Definition: postgres.h:335

References DatumGetCString(), elog, ERROR, get_fn_expr_argtype(), get_typlen(), MemoryContextAlloc(), PG_GETARG_DATUM, PG_RETURN_INT32, toast_datum_size(), and value.

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

Definition at line 3995 of file varlena.c.

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 }
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1215
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1502
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3981
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1467
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1335

References appendBinaryStringInfo(), appendStringInfoText(), CHECK_FOR_INTERRUPTS, cstring_to_text_with_len(), initStringInfo(), pfree(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, generate_unaccent_rules::str, text_position_cleanup(), text_position_get_match_ptr(), text_position_next(), text_position_setup(), VARDATA_ANY, VARSIZE_ANY, and VARSIZE_ANY_EXHDR.

Referenced by appendStringInfoRegexpSubstr(), check_replace_text_has_escape(), execute_extension_script(), and replace_text_regexp().

◆ replace_text_regexp()

text* replace_text_regexp ( text src_text,
text pattern_text,
text replace_text,
int  cflags,
Oid  collation,
int  search_start,
int  n 
)

Definition at line 4205 of file varlena.c.

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 }
#define lengthof(array)
Definition: c.h:775
unsigned int pg_wchar
Definition: mbprint.c:31
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:987
const void * data
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:142
Definition: regex.h:56
static int check_replace_text_has_escape(const text *replace_text)
Definition: varlena.c:4072
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4105

References appendBinaryStringInfo(), appendStringInfoRegexpSubstr(), appendStringInfoText(), buf, charlen_to_bytelen(), CHECK_FOR_INTERRUPTS, check_replace_text_has_escape(), cstring_to_text_with_len(), data, ereport, errcode(), errmsg(), ERROR, initStringInfo(), lengthof, palloc(), pfree(), pg_mb2wchar_with_len(), pg_regerror(), pg_regexec(), RE_compile_and_cache(), REG_NOMATCH, REG_NOSUB, REG_OKAY, replace_text(), regmatch_t::rm_eo, regmatch_t::rm_so, VARDATA_ANY, VARSIZE_ANY, and VARSIZE_ANY_EXHDR.

Referenced by textregexreplace(), textregexreplace_extended(), and textregexreplace_noopt().

◆ rest_of_char_same()

static bool rest_of_char_same ( const char *  s1,
const char *  s2,
int  len 
)
inlinestatic

Definition at line 6110 of file varlena.c.

6111 {
6112  while (len > 0)
6113  {
6114  len--;
6115  if (s1[len] != s2[len])
6116  return false;
6117  }
6118  return true;
6119 }

References len, s1, and s2.

Referenced by varstr_levenshtein().

◆ split_part()

Datum split_part ( PG_FUNCTION_ARGS  )

Definition at line 4367 of file varlena.c.

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 }
static void text_position_reset(TextPositionState *state)
Definition: varlena.c:1494

References Assert(), cstring_to_text(), cstring_to_text_with_len(), ereport, errcode(), errmsg(), ERROR, PG_GET_COLLATION, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, text_position_cleanup(), text_position_get_match_ptr(), text_position_next(), text_position_reset(), text_position_setup(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ split_text()

static bool split_text ( FunctionCallInfo  fcinfo,
SplitTextOutputData tstate 
)
static

Definition at line 4590 of file varlena.c.

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 }
static void split_text_accum_result(SplitTextOutputData *tstate, text *field_value, text *null_string, Oid collation)
Definition: varlena.c:4726

References CHECK_FOR_INTERRUPTS, cstring_to_text_with_len(), pfree(), PG_ARGISNULL, PG_GET_COLLATION, PG_GETARG_TEXT_PP, pg_mblen(), PG_NARGS, split_text_accum_result(), text_position_cleanup(), text_position_get_match_ptr(), text_position_next(), text_position_setup(), VARDATA_ANY, VARSIZE_ANY, and VARSIZE_ANY_EXHDR.

Referenced by text_to_array(), and text_to_table().

◆ split_text_accum_result()

static void split_text_accum_result ( SplitTextOutputData tstate,
text field_value,
text null_string,
Oid  collation 
)
static

Definition at line 4726 of file varlena.c.

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 }
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5332
static Datum values[MAXATTR]
Definition: bootstrap.c:156
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
TupleDesc tupdesc
Definition: varlena.c:107
ArrayBuildState * astate
Definition: varlena.c:105
Tuplestorestate * tupstore
Definition: varlena.c:106
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:750
static bool text_isequal(text *txt1, text *txt2, Oid collid)
Definition: varlena.c:4499

References accumArrayResult(), SplitTextOutputData::astate, CurrentMemoryContext, PointerGetDatum(), text_isequal(), SplitTextOutputData::tupdesc, tuplestore_putvalues(), SplitTextOutputData::tupstore, and values.

Referenced by split_text().

◆ SplitDirectoriesString()

bool SplitDirectoriesString ( char *  rawstring,
char  separator,
List **  namelist 
)

Definition at line 3583 of file varlena.c.

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 }
List * lappend(List *list, void *datum)
Definition: list.c:339
char * pstrdup(const char *in)
Definition: mcxt.c:1580
#define MAXPGPATH
#define NIL
Definition: pg_list.h:68
void canonicalize_path(char *path)
Definition: path.c:264
bool scanner_isspace(char ch)
Definition: scansup.c:117

References canonicalize_path(), lappend(), MAXPGPATH, NIL, pstrdup(), and scanner_isspace().

Referenced by load_libraries(), and PostmasterMain().

◆ SplitGUCList()

bool SplitGUCList ( char *  rawstring,
char  separator,
List **  namelist 
)

Definition at line 3704 of file varlena.c.

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 }

References lappend(), NIL, and scanner_isspace().

Referenced by check_debug_io_direct(), dumpFunc(), parse_hba_auth_opt(), pg_get_functiondef(), and PostmasterMain().

◆ SplitIdentifierString()

bool SplitIdentifierString ( char *  rawstring,
char  separator,
List **  namelist 
)

Definition at line 3456 of file varlena.c.

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 }
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:93
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37

References Assert(), downcase_truncate_identifier(), lappend(), len, NIL, pfree(), scanner_isspace(), and truncate_identifier().

Referenced by check_createrole_self_grant(), check_datestyle(), check_log_destination(), check_search_path(), check_temp_tablespaces(), check_wal_consistency_checking(), ExtractExtensionList(), parse_extension_control_file(), parse_output_parameters(), parse_publication_options(), plpgsql_extra_checks_check_hook(), PrepareTempTablespaces(), preprocessNamespacePath(), stringToQualifiedNameList(), and textToQualifiedNameList().

◆ string_agg_combine()

Datum string_agg_combine ( PG_FUNCTION_ARGS  )

Definition at line 5199 of file varlena.c.

5200 {
5201  StringInfo state1;
5202  StringInfo state2;
5203  MemoryContext agg_context;
5204 
5205  if (!AggCheckCallContext(fcinfo, &agg_context))
5206  elog(ERROR, "aggregate function called in non-aggregate context");
5207 
5208  state1 = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5209  state2 = PG_ARGISNULL(1) ? NULL : (StringInfo) PG_GETARG_POINTER(1);
5210 
5211  if (state2 == NULL)
5212  {
5213  /*
5214  * NULL state2 is easy, just return state1, which we know is already
5215  * in the agg_context
5216  */
5217  if (state1 == NULL)
5218  PG_RETURN_NULL();
5219  PG_RETURN_POINTER(state1);
5220  }
5221 
5222  if (state1 == NULL)
5223  {
5224  /* We must copy state2's data into the agg_context */
5225  MemoryContext old_context;
5226 
5227  old_context = MemoryContextSwitchTo(agg_context);
5228  state1 = makeStringAggState(fcinfo);
5229  appendBinaryStringInfo(state1, state2->data, state2->len);
5230  state1->cursor = state2->cursor;
5231  MemoryContextSwitchTo(old_context);
5232  }
5233  else if (state2->len > 0)
5234  {
5235  /* Combine ... state1->cursor does not change in this case */
5236  appendBinaryStringInfo(state1, state2->data, state2->len);
5237  }
5238 
5239  PG_RETURN_POINTER(state1);
5240 }

References AggCheckCallContext(), appendBinaryStringInfo(), StringInfoData::cursor, StringInfoData::data, elog, ERROR, StringInfoData::len, makeStringAggState(), MemoryContextSwitchTo(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, and PG_RETURN_POINTER.

◆ string_agg_deserialize()

Datum string_agg_deserialize ( PG_FUNCTION_ARGS  )

Definition at line 5280 of file varlena.c.

5281 {
5282  bytea *sstate;
5283  StringInfo result;
5285  char *data;
5286  int datalen;
5287 
5288  /* cannot be called directly because of internal-type argument */
5289  Assert(AggCheckCallContext(fcinfo, NULL));
5290 
5291  sstate = PG_GETARG_BYTEA_PP(0);
5292 
5293  /*
5294  * Initialize a StringInfo so that we can "receive" it using the standard
5295  * recv-function infrastructure.
5296  */
5298  VARSIZE_ANY_EXHDR(sstate));
5299 
5300  result = makeStringAggState(fcinfo);
5301 
5302  /* cursor */
5303  result->cursor = pq_getmsgint(&buf, 4);
5304 
5305  /* data */
5306  datalen = VARSIZE_ANY_EXHDR(sstate) - 4;
5307  data = (char *) pq_getmsgbytes(&buf, datalen);
5308  appendBinaryStringInfo(result, data, datalen);
5309 
5310  pq_getmsgend(&buf);
5311 
5312  PG_RETURN_POINTER(result);
5313 }
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:418
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:638
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:511
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:129

References AggCheckCallContext(), appendBinaryStringInfo(), Assert(), buf, StringInfoData::cursor, data, initReadOnlyStringInfo(), makeStringAggState(), PG_GETARG_BYTEA_PP, PG_RETURN_POINTER, pq_getmsgbytes(), pq_getmsgend(), pq_getmsgint(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 5316 of file varlena.c.

5317 {
5318  StringInfo state;
5319 
5320  /* cannot be called directly because of internal-type argument */
5321  Assert(AggCheckCallContext(fcinfo, NULL));
5322 
5323  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5324 
5325  if (state != NULL)
5326  {
5327  /* As per comment in transfn, strip data before the cursor position */
5329  state->len - state->cursor));
5330  }
5331  else
5332  PG_RETURN_NULL();
5333 }

References AggCheckCallContext(), Assert(), cstring_to_text_with_len(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, and PG_RETURN_TEXT_P.

◆ string_agg_serialize()

Datum string_agg_serialize ( PG_FUNCTION_ARGS  )

Definition at line 5249 of file varlena.c.

5250 {
5251  StringInfo state;
5253  bytea *result;
5254 
5255  /* cannot be called directly because of internal-type argument */
5256  Assert(AggCheckCallContext(fcinfo, NULL));
5257 
5259 
5260  pq_begintypsend(&buf);
5261 
5262  /* cursor */
5263  pq_sendint(&buf, state->cursor, 4);
5264 
5265  /* data */
5266  pq_sendbytes(&buf, state->data, state->len);
5267 
5268  result = pq_endtypsend(&buf);
5269 
5270  PG_RETURN_BYTEA_P(result);
5271 }
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:329
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:349
static void pq_sendint(StringInfo buf, uint32 i, int b)
Definition: pqformat.h:172

References AggCheckCallContext(), Assert(), buf, PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendbytes(), and pq_sendint().

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 5144 of file varlena.c.

5145 {
5146  StringInfo state;
5147 
5148  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5149 
5150  /* Append the value unless null, preceding it with the delimiter. */
5151  if (!PG_ARGISNULL(1))
5152  {
5154  bool isfirst = false;
5155 
5156  /*
5157  * You might think we can just throw away the first delimiter, however
5158  * we must keep it as we may be a parallel worker doing partial
5159  * aggregation building a state to send to the main process. We need
5160  * to keep the delimiter of every aggregation so that the combine
5161  * function can properly join up the strings of two separately
5162  * partially aggregated results. The first delimiter is only stripped
5163  * off in the final function. To know how much to strip off the front
5164  * of the string, we store the length of the first delimiter in the
5165  * StringInfo's cursor field, which we don't otherwise need here.
5166  */
5167  if (state == NULL)
5168  {
5169  state = makeStringAggState(fcinfo);
5170  isfirst = true;
5171  }
5172 
5173  if (!PG_ARGISNULL(2))
5174  {
5175  text *delim = PG_GETARG_TEXT_PP(2);
5176 
5177  appendStringInfoText(state, delim);
5178  if (isfirst)
5179  state->cursor = VARSIZE_ANY_EXHDR(delim);
5180  }
5181 
5183  }
5184 
5185  /*
5186  * The transition type for string_agg() is declared to be "internal",
5187  * which is a pass-by-value type the same size as a pointer.
5188  */
5189  if (state)
5191  PG_RETURN_NULL();
5192 }

References appendStringInfoText(), makeStringAggState(), PG_ARGISNULL, PG_GETARG_POINTER, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_POINTER, value, and VARSIZE_ANY_EXHDR.

◆ text_catenate()

static text * text_catenate ( text t1,
text t2 
)
static

Definition at line 765 of file varlena.c.

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 }

References len, palloc(), SET_VARSIZE, VARDATA, VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

Referenced by text_overlay(), and textcat().

◆ text_cmp()

static int text_cmp ( text arg1,
text arg2,
Oid  collid 
)
static

Definition at line 1593 of file varlena.c.

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 }

References collid, VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

Referenced by bttextcmp(), text_ge(), text_gt(), text_larger(), text_le(), text_lt(), text_smaller(), texteq(), and textne().

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 5460 of file varlena.c.

5461 {
5462  text *result;
5463 
5464  result = concat_internal("", 0, fcinfo);
5465  if (result == NULL)
5466  PG_RETURN_NULL();
5467  PG_RETURN_TEXT_P(result);
5468 }
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5380

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5475 of file varlena.c.

5476 {
5477  char *sep;
5478  text *result;
5479 
5480  /* return NULL when separator is NULL */
5481  if (PG_ARGISNULL(0))
5482  PG_RETURN_NULL();
5484 
5485  result = concat_internal(sep, 1, fcinfo);
5486  if (result == NULL)
5487  PG_RETURN_NULL();
5488  PG_RETURN_TEXT_P(result);
5489 }

References concat_internal(), PG_ARGISNULL, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_TEXT_P, and text_to_cstring().

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

Definition at line 5596 of file varlena.c.

5597 {
5598  text *fmt;
5600  const char *cp;
5601  const char *start_ptr;
5602  const char *end_ptr;
5603  text *result;
5604  int arg;
5605  bool funcvariadic;
5606  int nargs;
5607  Datum *elements = NULL;
5608  bool *nulls = NULL;
5609  Oid element_type = InvalidOid;
5610  Oid prev_type = InvalidOid;
5611  Oid prev_width_type = InvalidOid;
5612  FmgrInfo typoutputfinfo;
5613  FmgrInfo typoutputinfo_width;
5614 
5615  /* When format string is null, immediately return null */
5616  if (PG_ARGISNULL(0))
5617  PG_RETURN_NULL();
5618 
5619  /* If argument is marked VARIADIC, expand array into elements */
5620  if (get_fn_expr_variadic(fcinfo->flinfo))
5621  {
5622  ArrayType *arr;
5623  int16 elmlen;
5624  bool elmbyval;
5625  char elmalign;
5626  int nitems;
5627 
5628  /* Should have just the one argument */
5629  Assert(PG_NARGS() == 2);
5630 
5631  /* If argument is NULL, we treat it as zero-length array */
5632  if (PG_ARGISNULL(1))
5633  nitems = 0;
5634  else
5635  {
5636  /*
5637  * Non-null argument had better be an array. We assume that any
5638  * call context that could let get_fn_expr_variadic return true
5639  * will have checked that a VARIADIC-labeled parameter actually is
5640  * an array. So it should be okay to just Assert that it's an
5641  * array rather than doing a full-fledged error check.
5642  */
5644 
5645  /* OK, safe to fetch the array value */
5646  arr = PG_GETARG_ARRAYTYPE_P(1);
5647 
5648  /* Get info about array element type */
5649  element_type = ARR_ELEMTYPE(arr);
5650  get_typlenbyvalalign(element_type,
5651  &elmlen, &elmbyval, &elmalign);
5652 
5653  /* Extract all array elements */
5654  deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
5655  &elements, &nulls, &nitems);
5656  }
5657 
5658  nargs = nitems + 1;
5659  funcvariadic = true;
5660  }
5661  else
5662  {
5663  /* Non-variadic case, we'll process the arguments individually */
5664  nargs = PG_NARGS();
5665  funcvariadic = false;
5666  }
5667 
5668  /* Setup for main loop. */
5669  fmt = PG_GETARG_TEXT_PP(0);
5670  start_ptr = VARDATA_ANY(fmt);
5671  end_ptr = start_ptr + VARSIZE_ANY_EXHDR(fmt);
5672  initStringInfo(&str);
5673  arg = 1; /* next argument position to print */
5674 
5675  /* Scan format string, looking for conversion specifiers. */
5676  for (cp = start_ptr; cp < end_ptr; cp++)
5677  {
5678  int argpos;
5679  int widthpos;
5680  int flags;
5681  int width;
5682  Datum value;
5683  bool isNull;
5684  Oid typid;
5685 
5686  /*
5687  * If it's not the start of a conversion specifier, just copy it to
5688  * the output buffer.
5689  */
5690  if (*cp != '%')
5691  {
5693  continue;
5694  }
5695 
5696  ADVANCE_PARSE_POINTER(cp, end_ptr);
5697 
5698  /* Easy case: %% outputs a single % */
5699  if (*cp == '%')
5700  {
5702  continue;
5703  }
5704 
5705  /* Parse the optional portions of the format specifier */
5706  cp = text_format_parse_format(cp, end_ptr,
5707  &argpos, &widthpos,
5708  &flags, &width);
5709 
5710  /*
5711  * Next we should see the main conversion specifier. Whether or not
5712  * an argument position was present, it's known that at least one
5713  * character remains in the string at this point. Experience suggests
5714  * that it's worth checking that that character is one of the expected
5715  * ones before we try to fetch arguments, so as to produce the least
5716  * confusing response to a mis-formatted specifier.
5717  */
5718  if (strchr("sIL", *cp) == NULL)
5719  ereport(ERROR,
5720  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5721  errmsg("unrecognized format() type specifier \"%.*s\"",
5722  pg_mblen(cp), cp),
5723  errhint("For a single \"%%\" use \"%%%%\".")));
5724 
5725  /* If indirect width was specified, get its value */
5726  if (widthpos >= 0)
5727  {
5728  /* Collect the specified or next argument position */
5729  if (widthpos > 0)
5730  arg = widthpos;
5731  if (arg >= nargs)
5732  ereport(ERROR,
5733  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5734  errmsg("too few arguments for format()")));
5735 
5736  /* Get the value and type of the selected argument */
5737  if (!funcvariadic)
5738  {
5740  isNull = PG_ARGISNULL(arg);
5741  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5742  }
5743  else
5744  {
5745  value = elements[arg - 1];
5746  isNull = nulls[arg - 1];
5747  typid = element_type;
5748  }
5749  if (!OidIsValid(typid))
5750  elog(ERROR, "could not determine data type of format() input");
5751 
5752  arg++;
5753 
5754  /* We can treat NULL width the same as zero */
5755  if (isNull)
5756  width = 0;
5757  else if (typid == INT4OID)
5758  width = DatumGetInt32(value);
5759  else if (typid == INT2OID)
5760  width = DatumGetInt16(value);
5761  else
5762  {
5763  /* For less-usual datatypes, convert to text then to int */
5764  char *str;
5765 
5766  if (typid != prev_width_type)
5767  {
5768  Oid typoutputfunc;
5769  bool typIsVarlena;
5770 
5771  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5772  fmgr_info(typoutputfunc, &typoutputinfo_width);
5773  prev_width_type = typid;
5774  }
5775 
5776  str = OutputFunctionCall(&typoutputinfo_width, value);
5777 
5778  /* pg_strtoint32 will complain about bad data or overflow */
5779  width = pg_strtoint32(str);
5780 
5781  pfree(str);
5782  }
5783  }
5784 
5785  /* Collect the specified or next argument position */
5786  if (argpos > 0)
5787  arg = argpos;
5788  if (arg >= nargs)
5789  ereport(ERROR,
5790  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5791  errmsg("too few arguments for format()")));
5792 
5793  /* Get the value and type of the selected argument */
5794  if (!funcvariadic)
5795  {
5797  isNull = PG_ARGISNULL(arg);
5798  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5799  }
5800  else
5801  {
5802  value = elements[arg - 1];
5803  isNull = nulls[arg - 1];
5804  typid = element_type;
5805  }
5806  if (!OidIsValid(typid))
5807  elog(ERROR, "could not determine data type of format() input");
5808 
5809  arg++;
5810 
5811  /*
5812  * Get the appropriate typOutput function, reusing previous one if
5813  * same type as previous argument. That's particularly useful in the
5814  * variadic-array case, but often saves work even for ordinary calls.
5815  */
5816  if (typid != prev_type)
5817  {
5818  Oid typoutputfunc;
5819  bool typIsVarlena;
5820 
5821  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5822  fmgr_info(typoutputfunc, &typoutputfinfo);
5823  prev_type = typid;
5824  }
5825 
5826  /*
5827  * And now we can format the value.
5828  */
5829  switch (*cp)
5830  {
5831  case 's':
5832  case 'I':
5833  case 'L':
5834  text_format_string_conversion(&str, *cp, &typoutputfinfo,
5835  value, isNull,
5836  flags, width);
5837  break;
5838  default:
5839  /* should not get here, because of previous check */
5840  ereport(ERROR,
5841  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5842  errmsg("unrecognized format() type specifier \"%.*s\"",
5843  pg_mblen(cp), cp),
5844  errhint("For a single \"%%\" use \"%%%%\".")));
5845  break;
5846  }
5847  }
5848 
5849  /* Don't need deconstruct_array results anymore. */
5850  if (elements != NULL)
5851  pfree(elements);
5852  if (nulls != NULL)
5853  pfree(nulls);
5854 
5855  /* Generate results. */
5856  result = cstring_to_text_with_len(str.data, str.len);
5857  pfree(str.data);
5858 
5859  PG_RETURN_TEXT_P(result);
5860 }
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3613
signed short int16
Definition: c.h:480
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
static void const char * fmt
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2226
int32 pg_strtoint32(const char *s)
Definition: numutils.c:384
void * arg
static int16 DatumGetInt16(Datum X)
Definition: postgres.h:162
#define InvalidOid
Definition: postgres_ext.h:36
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:203
static void text_format_string_conversion(StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
Definition: varlena.c:5999
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:5922
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5583

References ADVANCE_PARSE_POINTER, appendStringInfoCharMacro, arg, ARR_ELEMTYPE, Assert(), cstring_to_text_with_len(), DatumGetInt16(), DatumGetInt32(), deconstruct_array(), elog, ereport, errcode(), errhint(), errmsg(), ERROR, fmgr_info(), fmt, get_base_element_type(), get_fn_expr_argtype(), get_fn_expr_variadic(), get_typlenbyvalalign(), getTypeOutputInfo(), initStringInfo(), InvalidOid, nitems, OidIsValid, OutputFunctionCall(), pfree(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_GETARG_TEXT_PP, pg_mblen(), PG_NARGS, PG_RETURN_NULL, PG_RETURN_TEXT_P, pg_strtoint32(), generate_unaccent_rules::str, text_format_parse_format(), text_format_string_conversion(), value, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by text_format_nv().

◆ text_format_append_string()

static void text_format_append_string ( StringInfo  buf,
const char *  str,
int  flags,
int  width 
)
static

Definition at line 6048 of file varlena.c.

6050 {
6051  bool align_to_left = false;
6052  int len;
6053 
6054  /* fast path for typical easy case */
6055  if (width == 0)
6056  {
6058  return;
6059  }
6060 
6061  if (width < 0)
6062  {
6063  /* Negative width: implicit '-' flag, then take absolute value */
6064  align_to_left = true;
6065  /* -INT_MIN is undefined */
6066  if (width <= INT_MIN)
6067  ereport(ERROR,
6068  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6069  errmsg("number is out of range")));
6070  width = -width;
6071  }
6072  else if (flags & TEXT_FORMAT_FLAG_MINUS)
6073  align_to_left = true;
6074 
6075  len = pg_mbstrlen(str);
6076  if (align_to_left)
6077  {
6078  /* left justify */
6080  if (len < width)
6081  appendStringInfoSpaces(buf, width - len);
6082  }
6083  else
6084  {
6085  /* right justify */
6086  if (len < width)
6087  appendStringInfoSpaces(buf, width - len);
6089  }
6090 }
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:1038
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:212
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5581

References appendStringInfoSpaces(), appendStringInfoString(), buf, ereport, errcode(), errmsg(), ERROR, len, pg_mbstrlen(), generate_unaccent_rules::str, and TEXT_FORMAT_FLAG_MINUS.

Referenced by text_format_string_conversion().

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 6100 of file varlena.c.

6101 {
6102  return text_format(fcinfo);
6103 }
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5596

References text_format().

◆ text_format_parse_digits()

static bool text_format_parse_digits ( const char **  ptr,
const char *  end_ptr,
int *  value 
)
static

Definition at line 5873 of file varlena.c.

5874 {
5875  bool found = false;
5876  const char *cp = *ptr;
5877  int val = 0;
5878 
5879  while (*cp >= '0' && *cp <= '9')
5880  {
5881  int8 digit = (*cp - '0');
5882 
5883  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5884  unlikely(pg_add_s32_overflow(val, digit, &val)))
5885  ereport(ERROR,
5886  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5887  errmsg("number is out of range")));
5888  ADVANCE_PARSE_POINTER(cp, end_ptr);
5889  found = true;
5890  }
5891 
5892  *ptr = cp;
5893  *value = val;
5894 
5895  return found;
5896 }
signed char int8
Definition: c.h:479
#define unlikely(x)
Definition: c.h:298
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140

References ADVANCE_PARSE_POINTER, ereport, errcode(), errmsg(), ERROR, pg_add_s32_overflow(), pg_mul_s32_overflow(), unlikely, val, and value.

Referenced by text_format_parse_format().

◆ text_format_parse_format()

static const char * text_format_parse_format ( const char *  start_ptr,
const char *  end_ptr,
int *  argpos,
int *  widthpos,
int *  flags,
int *  width 
)
static

Definition at line 5922 of file varlena.c.

5925 {
5926  const char *cp = start_ptr;
5927  int n;
5928 
5929  /* set defaults for output parameters */
5930  *argpos = -1;
5931  *widthpos = -1;
5932  *flags = 0;
5933  *width = 0;
5934 
5935  /* try to identify first number */
5936  if (text_format_parse_digits(&cp, end_ptr, &n))
5937  {
5938  if (*cp != '$')
5939  {
5940  /* Must be just a width and a type, so we're done */
5941  *width = n;
5942  return cp;
5943  }
5944  /* The number was argument position */
5945  *argpos = n;
5946  /* Explicit 0 for argument index is immediately refused */
5947  if (n == 0)
5948  ereport(ERROR,
5949  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5950  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5951  ADVANCE_PARSE_POINTER(cp, end_ptr);
5952  }
5953 
5954  /* Handle flags (only minus is supported now) */
5955  while (*cp == '-')
5956  {
5957  *flags |= TEXT_FORMAT_FLAG_MINUS;
5958  ADVANCE_PARSE_POINTER(cp, end_ptr);
5959  }
5960 
5961  if (*cp == '*')
5962  {
5963  /* Handle indirect width */
5964  ADVANCE_PARSE_POINTER(cp, end_ptr);
5965  if (text_format_parse_digits(&cp, end_ptr, &n))
5966  {
5967  /* number in this position must be closed by $ */
5968  if (*cp != '$')
5969  ereport(ERROR,
5970  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5971  errmsg("width argument position must be ended by \"$\"")));
5972  /* The number was width argument position */
5973  *widthpos = n;
5974  /* Explicit 0 for argument index is immediately refused */
5975  if (n == 0)
5976  ereport(ERROR,
5977  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5978  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5979  ADVANCE_PARSE_POINTER(cp, end_ptr);
5980  }
5981  else
5982  *widthpos = 0; /* width's argument position is unspecified */
5983  }
5984  else
5985  {
5986  /* Check for direct width specification */
5987  if (text_format_parse_digits(&cp, end_ptr, &n))
5988  *width = n;
5989  }
5990 
5991  /* cp should now be pointing at type character */
5992  return cp;
5993 }
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:5873

References ADVANCE_PARSE_POINTER, ereport, errcode(), errmsg(), ERROR, TEXT_FORMAT_FLAG_MINUS, and text_format_parse_digits().

Referenced by text_format().

◆ text_format_string_conversion()

static void text_format_string_conversion ( StringInfo  buf,
char  conversion,
FmgrInfo typOutputInfo,
Datum  value,
bool  isNull,
int  flags,
int  width 
)
static

Definition at line 5999 of file varlena.c.

6003 {
6004  char *str;
6005 
6006  /* Handle NULL arguments before trying to stringify the value. */
6007  if (isNull)
6008  {
6009  if (conversion == 's')
6010  text_format_append_string(buf, "", flags, width);
6011  else if (conversion == 'L')
6012  text_format_append_string(buf, "NULL", flags, width);
6013  else if (conversion == 'I')
6014  ereport(ERROR,
6015  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6016  errmsg("null values cannot be formatted as an SQL identifier")));
6017  return;
6018  }
6019 
6020  /* Stringify. */
6021  str = OutputFunctionCall(typOutputInfo, value);
6022 
6023  /* Escape. */
6024  if (conversion == 'I')
6025  {
6026  /* quote_identifier may or may not allocate a new string. */
6028  }
6029  else if (conversion == 'L')
6030  {
6031  char *qstr = quote_literal_cstr(str);
6032 
6033  text_format_append_string(buf, qstr, flags, width);
6034  /* quote_literal_cstr() always allocates a new string */
6035  pfree(qstr);
6036  }
6037  else
6038  text_format_append_string(buf, str, flags, width);
6039 
6040  /* Cleanup. */
6041  pfree(str);
6042 }
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:103
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11975
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:6048

References buf, ereport, errcode(), errmsg(), ERROR, OutputFunctionCall(), pfree(), quote_identifier(), quote_literal_cstr(), generate_unaccent_rules::str, text_format_append_string(), and value.

Referenced by text_format().

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

Definition at line 1775 of file varlena.c.

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 }

References PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and text_cmp().

Referenced by gbt_textge().

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

Definition at line 1760 of file varlena.c.

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 }

References PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and text_cmp().

Referenced by gbt_textgt().

◆ text_isequal()

static bool text_isequal ( text txt1,
text txt2,
Oid  collid 
)
static

Definition at line 4499 of file varlena.c.

4500 {
4502  collid,
4503  PointerGetDatum(txt1),
4504  PointerGetDatum(txt2)));
4505 }
static bool DatumGetBool(Datum X)
Definition: postgres.h:90
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1618

References collid, DatumGetBool(), DirectFunctionCall2Coll(), PointerGetDatum(), and texteq().

Referenced by split_text_accum_result().

◆ text_larger()

Datum text_larger ( PG_FUNCTION_ARGS  )

Definition at line 2570 of file varlena.c.

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 }

References PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, and text_cmp().

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

Definition at line 1745 of file varlena.c.

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 }

References PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and text_cmp().

Referenced by gbt_textle().

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

Definition at line 5496 of file varlena.c.

5497 {
5498  int n = PG_GETARG_INT32(1);
5499 
5500  if (n < 0)
5501  {
5502  text *str = PG_GETARG_TEXT_PP(0);
5503  const char *p = VARDATA_ANY(str);
5504  int len = VARSIZE_ANY_EXHDR(str);
5505  int rlen;
5506 
5507  n = pg_mbstrlen_with_len(p, len) + n;
5508  rlen = pg_mbcharcliplen(p, len, n);
5510  }
5511  else
5513 }
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:1058
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1126
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:885

References cstring_to_text_with_len(), len, PG_GETARG_DATUM, PG_GETARG_INT32, PG_GETARG_TEXT_PP, pg_mbcharcliplen(), pg_mbstrlen_with_len(), PG_RETURN_TEXT_P, generate_unaccent_rules::str, text_substring(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ text_length()

static int32 text_length ( Datum  str)
static

Definition at line 711 of file varlena.c.

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 }
#define DatumGetTextPP(X)
Definition: fmgr.h:292

References DatumGetTextPP, pg_database_encoding_max_length(), pg_mbstrlen_with_len(), PG_RETURN_INT32, generate_unaccent_rules::str, toast_raw_datum_size(), VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

Referenced by textlen(), and textoverlay_no_len().

◆ text_lt()

Datum text_lt ( PG_FUNCTION_ARGS  )

Definition at line 1730 of file varlena.c.

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 }

References PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, and text_cmp().

Referenced by gbt_textlt().

◆ text_name()

Datum text_name ( PG_FUNCTION_ARGS  )

Definition at line 3358 of file varlena.c.

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 }
NameData * Name
Definition: c.h:731
#define PG_RETURN_NAME(x)
Definition: fmgr.h:363
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1084
void * palloc0(Size size)
Definition: mcxt.c:1231

References len, NAMEDATALEN, NameStr, palloc0(), PG_GETARG_TEXT_PP, pg_mbcliplen(), PG_RETURN_NAME, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ text_overlay()

static text * text_overlay ( text t1,
text t2,
int  sp,
int  sl 
)
static

Definition at line 1115 of file varlena.c.

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 }
static text * text_catenate(text *t1, text *t2)
Definition: varlena.c:765

References ereport, errcode(), errmsg(), ERROR, pg_add_s32_overflow(), PointerGetDatum(), s1, s2, text_catenate(), and text_substring().

Referenced by textoverlay(), and textoverlay_no_len().

◆ text_pattern_ge()

Datum text_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 2850 of file varlena.c.

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 }

References internal_text_pattern_compare(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ text_pattern_gt()

Datum text_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 2866 of file varlena.c.

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 }

References internal_text_pattern_compare(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ text_pattern_le()

Datum text_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 2834 of file varlena.c.

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 }

References internal_text_pattern_compare(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ text_pattern_lt()

Datum text_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 2818 of file varlena.c.

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 }

References internal_text_pattern_compare(), PG_FREE_IF_COPY, PG_GETARG_TEXT_PP, and PG_RETURN_BOOL.

◆ text_position()

static int text_position ( text t1,
text t2,
Oid  collid 
)
static

Definition at line 1175 of file varlena.c.

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 }
static int text_position_get_match_pos(TextPositionState *state)
Definition: varlena.c:1478

References collid, text_position_cleanup(), text_position_get_match_pos(), text_position_next(), text_position_setup(), and VARSIZE_ANY_EXHDR.

Referenced by textpos().

◆ text_position_cleanup()

static void text_position_cleanup ( TextPositionState state)
static

Definition at line 1502 of file varlena.c.

1503 {
1504  /* no cleanup needed */
1505 }

Referenced by replace_text(), split_part(), split_text(), and text_position().

◆ text_position_get_match_pos()

static int text_position_get_match_pos ( TextPositionState state)
static

Definition at line 1478 of file varlena.c.

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 }

References pg_mbstrlen_with_len().

Referenced by text_position().

◆ text_position_get_match_ptr()

static char * text_position_get_match_ptr ( TextPositionState state)
static

Definition at line 1467 of file varlena.c.

1468 {
1469  return state->last_match;
1470 }

Referenced by replace_text(), split_part(), and split_text().

◆ text_position_next()

static bool text_position_next ( TextPositionState state)
static

Definition at line 1335 of file varlena.c.

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 }
static char * text_position_next_internal(char *start_ptr, TextPositionState *state)
Definition: varlena.c:1399

References Assert(), pg_mblen(), and text_position_next_internal().

Referenced by replace_text(), split_part(), split_text(), and text_position().

◆ text_position_next_internal()

static char * text_position_next_internal ( char *  start_ptr,
TextPositionState state 
)
static

Definition at line 1399 of file varlena.c.

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 }

References Assert().

Referenced by text_position_next().

◆ text_position_reset()

static void text_position_reset ( TextPositionState state)
static

Definition at line 1494 of file varlena.c.

1495 {
1496  state->last_match = NULL;
1497  state->refpoint = state->str1;
1498  state->refpos = 0;
1499 }

Referenced by split_part().

◆ text_position_setup()

static void text_position_setup ( text t1,
text t2,
Oid  collid,
TextPositionState state 
)
static

Definition at line 1215 of file varlena.c.

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 }
int GetDatabaseEncoding(void)
Definition: mbutils.c:1262
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1514
bool pg_locale_deterministic(pg_locale_t locale)
Definition: pg_locale.c:1494
@ PG_UTF8
Definition: pg_wchar.h:232

References Assert(), check_collation_set(), collid, ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), i, lc_collate_is_c(), pg_database_encoding_max_length(), pg_locale_deterministic(), pg_newlocale_from_collation(), PG_UTF8, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text(), split_part(), split_text(), and text_position().

◆ text_reverse()

Datum text_reverse ( PG_FUNCTION_ARGS  )

Definition at line 5541 of file varlena.c.

5542 {
5543  text *str = PG_GETARG_TEXT_PP(0);
5544  const char *p = VARDATA_ANY(str);
5545  int len = VARSIZE_ANY_EXHDR(str);
5546  const char *endp = p + len;
5547  text *result;
5548  char *dst;
5549 
5550  result = palloc(len + VARHDRSZ);
5551  dst = (char *) VARDATA(result) + len;
5552  SET_VARSIZE(result, len + VARHDRSZ);
5553 
5555  {
5556  /* multibyte version */
5557  while (p < endp)
5558  {
5559  int sz;
5560 
5561  sz = pg_mblen(p);
5562  dst -= sz;
5563  memcpy(dst, p, sz);
5564  p += sz;
5565  }
5566  }
5567  else
5568  {
5569  /* single byte version */
5570  while (p < endp)
5571  *(--dst) = *p++;
5572  }
5573 
5574  PG_RETURN_TEXT_P(result);
5575 }

References len, palloc(), pg_database_encoding_max_length(), PG_GETARG_TEXT_PP, pg_mblen(), PG_RETURN_TEXT_P, SET_VARSIZE, generate_unaccent_rules::str, VARDATA, VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

◆ text_right()

Datum text_right ( PG_FUNCTION_ARGS  )

Definition at line 5520 of file varlena.c.

5521 {
5522  text *str = PG_GETARG_TEXT_PP(0);
5523  const char *p = VARDATA_ANY(str);
5524  int len = VARSIZE_ANY_EXHDR(str);
5525  int n = PG_GETARG_INT32(1);
5526  int off;
5527 
5528  if (n < 0)
5529  n = -n;
5530  else
5531  n = pg_mbstrlen_with_len(p, len) - n;
5532  off = pg_mbcharcliplen(p, len, n);
5533 
5535 }

References cstring_to_text_with_len(), len, PG_GETARG_INT32, PG_GETARG_TEXT_PP, pg_mbcharcliplen(), pg_mbstrlen_with_len(), PG_RETURN_TEXT_P, generate_unaccent_rules::str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ text_smaller()

Datum text_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2582 of file varlena.c.

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 }

References PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, and text_cmp().

◆ text_starts_with()

Datum text_starts_with ( PG_FUNCTION_ARGS  )

Definition at line 1790 of file varlena.c.

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 }

References check_collation_set(), collid, DatumGetTextPP, ereport, errcode(), errmsg(), ERROR, lc_collate_is_c(), PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_DATUM, pg_locale_deterministic(), pg_newlocale_from_collation(), PG_RETURN_BOOL, text_substring(), toast_raw_datum_size(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by spg_text_leaf_consistent().

◆ text_substr()

◆ text_substr_no_len()

Datum text_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 866 of file varlena.c.

867 {
869  PG_GETARG_INT32(1),
870  -1, true));
871 }

References