PostgreSQL Source Code  git master
varlena.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <limits.h>
#include "access/detoast.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "common/int.h"
#include "lib/hyperloglog.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "parser/scansup.h"
#include "port/pg_bswap.h"
#include "regex/regex.h"
#include "utils/builtins.h"
#include "utils/bytea.h"
#include "utils/hashutils.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
 

Macros

#define TEXTBUFLEN   1024
 
#define DatumGetUnknownP(X)   ((unknown *) PG_DETOAST_DATUM(X))
 
#define DatumGetUnknownPCopy(X)   ((unknown *) PG_DETOAST_DATUM_COPY(X))
 
#define PG_GETARG_UNKNOWN_P(n)   DatumGetUnknownP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_UNKNOWN_P_COPY(n)   DatumGetUnknownPCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_UNKNOWN_P(x)   PG_RETURN_POINTER(x)
 
#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 REGEXP_REPLACE_BACKREF_CNT   10
 
#define HEXBASE   16
 
#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 unknown
 
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 int varstrcmp_abbrev (Datum x, Datum y, 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 Datum text_to_array_internal (PG_FUNCTION_ARGS)
 
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)
 
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 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 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 bool check_replace_text_has_escape_char (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, void *regexp, text *replace_text, bool glob)
 
Datum split_text (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 array_to_text (PG_FUNCTION_ARGS)
 
Datum array_to_text_null (PG_FUNCTION_ARGS)
 
Datum to_hex32 (PG_FUNCTION_ARGS)
 
Datum to_hex64 (PG_FUNCTION_ARGS)
 
Datum pg_column_size (PG_FUNCTION_ARGS)
 
Datum string_agg_transfn (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)
 

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:1071
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
int errmsg(const char *fmt,...)
Definition: elog.c:822

Definition at line 5417 of file varlena.c.

Referenced by text_format(), text_format_parse_digits(), and text_format_parse_format().

◆ CmpCall

#define CmpCall (   cmpfunc)
Value:
#define DatumGetInt32(X)
Definition: postgres.h:472
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_GET_COLLATION()
Definition: fmgr.h:193
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:813

Definition at line 2947 of file varlena.c.

Referenced by namegetext(), namegttext(), nameletext(), namelttext(), textgename(), textgtname(), textlename(), and textltname().

◆ DatumGetUnknownP

#define DatumGetUnknownP (   X)    ((unknown *) PG_DETOAST_DATUM(X))

Definition at line 100 of file varlena.c.

◆ DatumGetUnknownPCopy

#define DatumGetUnknownPCopy (   X)    ((unknown *) PG_DETOAST_DATUM_COPY(X))

Definition at line 101 of file varlena.c.

◆ DatumGetVarStringP

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

Definition at line 106 of file varlena.c.

◆ DatumGetVarStringPP

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

Definition at line 107 of file varlena.c.

Referenced by varlenafastcmp_locale(), varstr_abbrev_convert(), and varstrfastcmp_c().

◆ DIG

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

Definition at line 263 of file varlena.c.

Referenced by byteaout().

◆ HEXBASE

#define HEXBASE   16

Definition at line 4995 of file varlena.c.

Referenced by to_hex32(), and to_hex64().

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

Definition at line 5957 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P

#define PG_GETARG_UNKNOWN_P (   n)    DatumGetUnknownP(PG_GETARG_DATUM(n))

Definition at line 102 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P_COPY

#define PG_GETARG_UNKNOWN_P_COPY (   n)    DatumGetUnknownPCopy(PG_GETARG_DATUM(n))

Definition at line 103 of file varlena.c.

◆ PG_RETURN_UNKNOWN_P

#define PG_RETURN_UNKNOWN_P (   x)    PG_RETURN_POINTER(x)

Definition at line 104 of file varlena.c.

◆ PG_STR_GET_BYTEA

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

Definition at line 3202 of file varlena.c.

Referenced by bytea_substring().

◆ REGEXP_REPLACE_BACKREF_CNT

#define REGEXP_REPLACE_BACKREF_CNT   10

Definition at line 4393 of file varlena.c.

Referenced by replace_text_regexp().

◆ TEXT_FORMAT_FLAG_MINUS

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

Definition at line 5415 of file varlena.c.

Referenced by text_format_append_string(), and text_format_parse_format().

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 98 of file varlena.c.

Referenced by varstr_cmp(), and varstr_sortsupport().

◆ VAL

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

Definition at line 262 of file varlena.c.

Referenced by byteain().

Typedef Documentation

◆ unknown

typedef struct varlena unknown

Definition at line 43 of file varlena.c.

◆ VarString

typedef struct varlena VarString

Definition at line 44 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 4299 of file varlena.c.

References appendBinaryStringInfo(), appendStringInfoChar(), Assert, charlen_to_bytelen(), idx(), pg_database_encoding_max_length(), pg_mblen(), regmatch_t::rm_eo, regmatch_t::rm_so, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text_regexp().

4302 {
4303  const char *p = VARDATA_ANY(replace_text);
4304  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4305  int eml = pg_database_encoding_max_length();
4306 
4307  for (;;)
4308  {
4309  const char *chunk_start = p;
4310  int so;
4311  int eo;
4312 
4313  /* Find next escape char. */
4314  if (eml == 1)
4315  {
4316  for (; p < p_end && *p != '\\'; p++)
4317  /* nothing */ ;
4318  }
4319  else
4320  {
4321  for (; p < p_end && *p != '\\'; p += pg_mblen(p))
4322  /* nothing */ ;
4323  }
4324 
4325  /* Copy the text we just scanned over, if any. */
4326  if (p > chunk_start)
4327  appendBinaryStringInfo(str, chunk_start, p - chunk_start);
4328 
4329  /* Done if at end of string, else advance over escape char. */
4330  if (p >= p_end)
4331  break;
4332  p++;
4333 
4334  if (p >= p_end)
4335  {
4336  /* Escape at very end of input. Treat same as unexpected char */
4337  appendStringInfoChar(str, '\\');
4338  break;
4339  }
4340 
4341  if (*p >= '1' && *p <= '9')
4342  {
4343  /* Use the back reference of regexp. */
4344  int idx = *p - '0';
4345 
4346  so = pmatch[idx].rm_so;
4347  eo = pmatch[idx].rm_eo;
4348  p++;
4349  }
4350  else if (*p == '&')
4351  {
4352  /* Use the entire matched string. */
4353  so = pmatch[0].rm_so;
4354  eo = pmatch[0].rm_eo;
4355  p++;
4356  }
4357  else if (*p == '\\')
4358  {
4359  /* \\ means transfer one \ to output. */
4360  appendStringInfoChar(str, '\\');
4361  p++;
4362  continue;
4363  }
4364  else
4365  {
4366  /*
4367  * If escape char is not followed by any expected char, just treat
4368  * it as ordinary data to copy. (XXX would it be better to throw
4369  * an error?)
4370  */
4371  appendStringInfoChar(str, '\\');
4372  continue;
4373  }
4374 
4375  if (so != -1 && eo != -1)
4376  {
4377  /*
4378  * Copy the text that is back reference of regexp. Note so and eo
4379  * are counted in characters not bytes.
4380  */
4381  char *chunk_start;
4382  int chunk_len;
4383 
4384  Assert(so >= data_pos);
4385  chunk_start = start_ptr;
4386  chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
4387  chunk_len = charlen_to_bytelen(chunk_start, eo - so);
4388  appendBinaryStringInfo(str, chunk_start, chunk_len);
4389  }
4390  }
4391 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
regoff_t rm_so
Definition: regex.h:85
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:263
regoff_t rm_eo
Definition: regex.h:86
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:757
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
#define Assert(condition)
Definition: c.h:733
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ appendStringInfoText()

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

Definition at line 4177 of file varlena.c.

References appendBinaryStringInfo(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text(), replace_text_regexp(), string_agg_transfn(), xml_send(), xmlcomment(), and XmlTableGetValue().

4178 {
4180 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

Definition at line 4836 of file varlena.c.

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

4837 {
4839  char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4840 
4841  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4842 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4878
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
char * text_to_cstring(const text *t)
Definition: varlena.c:204

◆ 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 4878 of file varlena.c.

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(), StringInfoData::data, ArrayMetaState::element_type, fetch_att, FunctionCallInfoBaseData::flinfo, fmgr_info_cxt(), FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, get_type_io_data(), i, initStringInfo(), IOFunc_output, StringInfoData::len, MemoryContextAlloc(), 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().

4880 {
4881  text *result;
4882  int nitems,
4883  *dims,
4884  ndims;
4885  Oid element_type;
4886  int typlen;
4887  bool typbyval;
4888  char typalign;
4890  bool printed = false;
4891  char *p;
4892  bits8 *bitmap;
4893  int bitmask;
4894  int i;
4895  ArrayMetaState *my_extra;
4896 
4897  ndims = ARR_NDIM(v);
4898  dims = ARR_DIMS(v);
4899  nitems = ArrayGetNItems(ndims, dims);
4900 
4901  /* if there are no elements, return an empty string */
4902  if (nitems == 0)
4903  return cstring_to_text_with_len("", 0);
4904 
4905  element_type = ARR_ELEMTYPE(v);
4906  initStringInfo(&buf);
4907 
4908  /*
4909  * We arrange to look up info about element type, including its output
4910  * conversion proc, only once per series of calls, assuming the element
4911  * type doesn't change underneath us.
4912  */
4913  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4914  if (my_extra == NULL)
4915  {
4916  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4917  sizeof(ArrayMetaState));
4918  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4919  my_extra->element_type = ~element_type;
4920  }
4921 
4922  if (my_extra->element_type != element_type)
4923  {
4924  /*
4925  * Get info about element type, including its output conversion proc
4926  */
4927  get_type_io_data(element_type, IOFunc_output,
4928  &my_extra->typlen, &my_extra->typbyval,
4929  &my_extra->typalign, &my_extra->typdelim,
4930  &my_extra->typioparam, &my_extra->typiofunc);
4931  fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
4932  fcinfo->flinfo->fn_mcxt);
4933  my_extra->element_type = element_type;
4934  }
4935  typlen = my_extra->typlen;
4936  typbyval = my_extra->typbyval;
4937  typalign = my_extra->typalign;
4938 
4939  p = ARR_DATA_PTR(v);
4940  bitmap = ARR_NULLBITMAP(v);
4941  bitmask = 1;
4942 
4943  for (i = 0; i < nitems; i++)
4944  {
4945  Datum itemvalue;
4946  char *value;
4947 
4948  /* Get source element, checking for NULL */
4949  if (bitmap && (*bitmap & bitmask) == 0)
4950  {
4951  /* if null_string is NULL, we just ignore null elements */
4952  if (null_string != NULL)
4953  {
4954  if (printed)
4955  appendStringInfo(&buf, "%s%s", fldsep, null_string);
4956  else
4957  appendStringInfoString(&buf, null_string);
4958  printed = true;
4959  }
4960  }
4961  else
4962  {
4963  itemvalue = fetch_att(p, typbyval, typlen);
4964 
4965  value = OutputFunctionCall(&my_extra->proc, itemvalue);
4966 
4967  if (printed)
4968  appendStringInfo(&buf, "%s%s", fldsep, value);
4969  else
4970  appendStringInfoString(&buf, value);
4971  printed = true;
4972 
4973  p = att_addlength_pointer(p, typlen, p);
4974  p = (char *) att_align_nominal(p, typalign);
4975  }
4976 
4977  /* advance bitmap pointer if any */
4978  if (bitmap)
4979  {
4980  bitmask <<= 1;
4981  if (bitmask == 0x100)
4982  {
4983  bitmap++;
4984  bitmask = 1;
4985  }
4986  }
4987  }
4988 
4989  result = cstring_to_text_with_len(buf.data, buf.len);
4990  pfree(buf.data);
4991 
4992  return result;
4993 }
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:146
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
static struct @145 value
unsigned int Oid
Definition: postgres_ext.h:31
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
bool typbyval
Definition: array.h:228
void pfree(void *pointer)
Definition: mcxt.c:1056
char typalign
Definition: pg_type.h:170
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ARR_DIMS(a)
Definition: array.h:282
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define ARR_DATA_PTR(a)
Definition: array.h:310
int16 typlen
Definition: array.h:227
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
char typdelim
Definition: array.h:230
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:174
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uint8 bits8
Definition: c.h:366
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * flinfo
Definition: fmgr.h:87
Oid typioparam
Definition: array.h:231
void * fn_extra
Definition: fmgr.h:64
#define ARR_NDIM(a)
Definition: array.h:278
Oid typiofunc
Definition: array.h:232
char typalign
Definition: array.h:229
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:73
FmgrInfo proc
Definition: array.h:233
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
int i
Oid element_type
Definition: array.h:226
Definition: c.h:550
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define ARR_NULLBITMAP(a)
Definition: array.h:288
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:2103

◆ array_to_text_null()

Datum array_to_text_null ( PG_FUNCTION_ARGS  )

Definition at line 4852 of file varlena.c.

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().

4853 {
4854  ArrayType *v;
4855  char *fldsep;
4856  char *null_string;
4857 
4858  /* returns NULL when first or second parameter is NULL */
4859  if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4860  PG_RETURN_NULL();
4861 
4862  v = PG_GETARG_ARRAYTYPE_P(0);
4863  fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4864 
4865  /* NULL null string is passed through as a null pointer */
4866  if (!PG_ARGISNULL(2))
4867  null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
4868  else
4869  null_string = NULL;
4870 
4871  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
4872 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4878
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
char * text_to_cstring(const text *t)
Definition: varlena.c:204
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ bpcharfastcmp_c()

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

Definition at line 2166 of file varlena.c.

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

Referenced by varstr_sortsupport().

2167 {
2168  BpChar *arg1 = DatumGetBpCharPP(x);
2169  BpChar *arg2 = DatumGetBpCharPP(y);
2170  char *a1p,
2171  *a2p;
2172  int len1,
2173  len2,
2174  result;
2175 
2176  a1p = VARDATA_ANY(arg1);
2177  a2p = VARDATA_ANY(arg2);
2178 
2179  len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2180  len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2181 
2182  result = memcmp(a1p, a2p, Min(len1, len2));
2183  if ((result == 0) && (len1 != len2))
2184  result = (len1 < len2) ? -1 : 1;
2185 
2186  /* We can't afford to leak memory here. */
2187  if (PointerGetDatum(arg1) != x)
2188  pfree(arg1);
2189  if (PointerGetDatum(arg2) != y)
2190  pfree(arg2);
2191 
2192  return result;
2193 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PointerGetDatum(X)
Definition: postgres.h:556
#define Min(x, y)
Definition: c.h:905
void pfree(void *pointer)
Definition: mcxt.c:1056
int bpchartruelen(char *s, int len)
Definition: varchar.c:671
#define DatumGetBpCharPP(X)
Definition: fmgr.h:287
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550

◆ btnametextcmp()

Datum btnametextcmp ( PG_FUNCTION_ARGS  )

Definition at line 2916 of file varlena.c.

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().

2917 {
2918  Name arg1 = PG_GETARG_NAME(0);
2919  text *arg2 = PG_GETARG_TEXT_PP(1);
2920  int32 result;
2921 
2922  result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
2923  VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
2924  PG_GET_COLLATION());
2925 
2926  PG_FREE_IF_COPY(arg2, 1);
2927 
2928  PG_RETURN_INT32(result);
2929 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GET_COLLATION()
Definition: fmgr.h:193
signed int int32
Definition: c.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1482
Definition: c.h:604
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:610
Definition: c.h:550
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 3099 of file varlena.c.

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

3100 {
3101  text *arg1 = PG_GETARG_TEXT_PP(0);
3102  text *arg2 = PG_GETARG_TEXT_PP(1);
3103  int result;
3104 
3105  result = internal_text_pattern_compare(arg1, arg2);
3106 
3107  PG_FREE_IF_COPY(arg1, 0);
3108  PG_FREE_IF_COPY(arg2, 1);
3109 
3110  PG_RETURN_INT32(result);
3111 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3013
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 3115 of file varlena.c.

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

3116 {
3118  MemoryContext oldcontext;
3119 
3120  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
3121 
3122  /* Use generic string SortSupport, forcing "C" collation */
3123  varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID);
3124 
3125  MemoryContextSwitchTo(oldcontext);
3126 
3127  PG_RETURN_VOID();
3128 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1967
#define PG_RETURN_VOID()
Definition: fmgr.h:339

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

Definition at line 1925 of file varlena.c.

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

Referenced by gbt_textcmp(), and leftmostvalue_text().

1926 {
1927  text *arg1 = PG_GETARG_TEXT_PP(0);
1928  text *arg2 = PG_GETARG_TEXT_PP(1);
1929  int32 result;
1930 
1931  result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1932 
1933  PG_FREE_IF_COPY(arg1, 0);
1934  PG_FREE_IF_COPY(arg2, 1);
1935 
1936  PG_RETURN_INT32(result);
1937 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GET_COLLATION()
Definition: fmgr.h:193
signed int int32
Definition: c.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1698
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ bttextnamecmp()

Datum bttextnamecmp ( PG_FUNCTION_ARGS  )

Definition at line 2932 of file varlena.c.

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().

2933 {
2934  text *arg1 = PG_GETARG_TEXT_PP(0);
2935  Name arg2 = PG_GETARG_NAME(1);
2936  int32 result;
2937 
2938  result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
2939  NameStr(*arg2), strlen(NameStr(*arg2)),
2940  PG_GET_COLLATION());
2941 
2942  PG_FREE_IF_COPY(arg1, 0);
2943 
2944  PG_RETURN_INT32(result);
2945 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GET_COLLATION()
Definition: fmgr.h:193
signed int int32
Definition: c.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1482
Definition: c.h:604
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:610
Definition: c.h:550
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1940 of file varlena.c.

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

1941 {
1943  Oid collid = ssup->ssup_collation;
1944  MemoryContext oldcontext;
1945 
1946  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1947 
1948  /* Use generic string SortSupport */
1949  varstr_sortsupport(ssup, TEXTOID, collid);
1950 
1951  MemoryContextSwitchTo(oldcontext);
1952 
1953  PG_RETURN_VOID();
1954 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
unsigned int Oid
Definition: postgres_ext.h:31
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1967
#define PG_RETURN_VOID()
Definition: fmgr.h:339

◆ build_concat_foutcache()

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

Definition at line 5176 of file varlena.c.

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().

5177 {
5178  FmgrInfo *foutcache;
5179  int i;
5180 
5181  /* We keep the info in fn_mcxt so it survives across calls */
5182  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5183  PG_NARGS() * sizeof(FmgrInfo));
5184 
5185  for (i = argidx; i < PG_NARGS(); i++)
5186  {
5187  Oid valtype;
5188  Oid typOutput;
5189  bool typIsVarlena;
5190 
5191  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5192  if (!OidIsValid(valtype))
5193  elog(ERROR, "could not determine data type of concat() input");
5194 
5195  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5196  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5197  }
5198 
5199  fcinfo->flinfo->fn_extra = foutcache;
5200 
5201  return foutcache;
5202 }
Definition: fmgr.h:56
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
MemoryContext fn_mcxt
Definition: fmgr.h:65
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:639
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
FmgrInfo * flinfo
Definition: fmgr.h:87
struct FmgrInfo FmgrInfo
#define PG_NARGS()
Definition: fmgr.h:198
void * fn_extra
Definition: fmgr.h:64
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:228
int i

◆ bytea_catenate()

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

Definition at line 3169 of file varlena.c.

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

Referenced by bytea_overlay(), and byteacat().

3170 {
3171  bytea *result;
3172  int len1,
3173  len2,
3174  len;
3175  char *ptr;
3176 
3177  len1 = VARSIZE_ANY_EXHDR(t1);
3178  len2 = VARSIZE_ANY_EXHDR(t2);
3179 
3180  /* paranoia ... probably should throw error instead? */
3181  if (len1 < 0)
3182  len1 = 0;
3183  if (len2 < 0)
3184  len2 = 0;
3185 
3186  len = len1 + len2 + VARHDRSZ;
3187  result = (bytea *) palloc(len);
3188 
3189  /* Set size of result string... */
3190  SET_VARSIZE(result, len);
3191 
3192  /* Fill data field of result string... */
3193  ptr = VARDATA(result);
3194  if (len1 > 0)
3195  memcpy(ptr, VARDATA_ANY(t1), len1);
3196  if (len2 > 0)
3197  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
3198 
3199  return result;
3200 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:556
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:550
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ bytea_overlay()

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

Definition at line 3326 of file varlena.c.

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

Referenced by byteaoverlay(), and byteaoverlay_no_len().

3327 {
3328  bytea *result;
3329  bytea *s1;
3330  bytea *s2;
3331  int sp_pl_sl;
3332 
3333  /*
3334  * Check for possible integer-overflow cases. For negative sp, throw a
3335  * "substring length" error because that's what should be expected
3336  * according to the spec's definition of OVERLAY().
3337  */
3338  if (sp <= 0)
3339  ereport(ERROR,
3340  (errcode(ERRCODE_SUBSTRING_ERROR),
3341  errmsg("negative substring length not allowed")));
3342  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
3343  ereport(ERROR,
3344  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3345  errmsg("integer out of range")));
3346 
3347  s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
3348  s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
3349  result = bytea_catenate(s1, t2);
3350  result = bytea_catenate(result, s2);
3351 
3352  return result;
3353 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3169
int errcode(int sqlerrcode)
Definition: elog.c:608
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3244
#define ERROR
Definition: elog.h:43
char * s1
#define ereport(elevel, rest)
Definition: elog.h:141
char * s2
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 4155 of file varlena.c.

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

4156 {
4158  MemoryContext oldcontext;
4159 
4160  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
4161 
4162  /* Use generic string SortSupport, forcing "C" collation */
4163  varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
4164 
4165  MemoryContextSwitchTo(oldcontext);
4166 
4167  PG_RETURN_VOID();
4168 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1967
#define PG_RETURN_VOID()
Definition: fmgr.h:339

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 504 of file varlena.c.

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

505 {
507 
508  /* cannot be called directly because of internal-type argument */
509  Assert(AggCheckCallContext(fcinfo, NULL));
510 
511  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
512 
513  if (state != NULL)
514  {
515  bytea *result;
516 
517  result = (bytea *) palloc(state->len + VARHDRSZ);
518  SET_VARSIZE(result, state->len + VARHDRSZ);
519  memcpy(VARDATA(result), state->data, state->len);
520  PG_RETURN_BYTEA_P(result);
521  }
522  else
523  PG_RETURN_NULL();
524 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:556
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
ts_parserstate state
Definition: tsquery.c:81
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:733
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3571
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:550
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 472 of file varlena.c.

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

473 {
475 
476  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
477 
478  /* Append the value unless null. */
479  if (!PG_ARGISNULL(1))
480  {
482 
483  /* On the first time through, we ignore the delimiter. */
484  if (state == NULL)
485  state = makeStringAggState(fcinfo);
486  else if (!PG_ARGISNULL(2))
487  {
488  bytea *delim = PG_GETARG_BYTEA_PP(2);
489 
491  }
492 
494  }
495 
496  /*
497  * The transition type for string_agg() is declared to be "internal",
498  * which is a pass-by-value type the same size as a pointer.
499  */
500  PG_RETURN_POINTER(state);
501 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
StringInfoData * StringInfo
Definition: stringinfo.h:44
static struct @145 value
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
ts_parserstate state
Definition: tsquery.c:81
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5104
Definition: c.h:550
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 3221 of file varlena.c.

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

3222 {
3224  PG_GETARG_INT32(1),
3225  PG_GETARG_INT32(2),
3226  false));
3227 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3244

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3235 of file varlena.c.

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

3236 {
3238  PG_GETARG_INT32(1),
3239  -1,
3240  true));
3241 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3244

◆ bytea_substring()

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

Definition at line 3244 of file varlena.c.

References DatumGetByteaPSlice, ereport, errcode(), errmsg(), ERROR, Max, and PG_STR_GET_BYTEA.

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

3248 {
3249  int S1; /* adjusted start position */
3250  int L1; /* adjusted substring length */
3251 
3252  S1 = Max(S, 1);
3253 
3254  if (length_not_specified)
3255  {
3256  /*
3257  * Not passed a length - DatumGetByteaPSlice() grabs everything to the
3258  * end of the string if we pass it a negative value for length.
3259  */
3260  L1 = -1;
3261  }
3262  else
3263  {
3264  /* end position */
3265  int E = S + L;
3266 
3267  /*
3268  * A negative value for L is the only way for the end position to be
3269  * before the start. SQL99 says to throw an error.
3270  */
3271  if (E < S)
3272  ereport(ERROR,
3273  (errcode(ERRCODE_SUBSTRING_ERROR),
3274  errmsg("negative substring length not allowed")));
3275 
3276  /*
3277  * A zero or negative value for the end position can happen if the
3278  * start was negative or one. SQL99 says to return a zero-length
3279  * string.
3280  */
3281  if (E < 1)
3282  return PG_STR_GET_BYTEA("");
3283 
3284  L1 = E - S1;
3285  }
3286 
3287  /*
3288  * If the start position is past the end of the string, SQL99 says to
3289  * return a zero-length string -- DatumGetByteaPSlice() will do that for
3290  * us. Convert to zero-based starting position
3291  */
3292  return DatumGetByteaPSlice(str, S1 - 1, L1);
3293 }
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:297
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:3202
#define ERROR
Definition: elog.h:43
#define S(n, x)
Definition: sha1.c:55
#define ereport(elevel, rest)
Definition: elog.h:141
#define Max(x, y)
Definition: c.h:899
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 3154 of file varlena.c.

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

3155 {
3156  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3157  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3158 
3160 }
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3169
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
Definition: c.h:550

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

Definition at line 4133 of file varlena.c.

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

Referenced by gbt_bitcmp(), gbt_byteacmp(), and leftmostvalue_char().

4134 {
4135  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4136  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4137  int len1,
4138  len2;
4139  int cmp;
4140 
4141  len1 = VARSIZE_ANY_EXHDR(arg1);
4142  len2 = VARSIZE_ANY_EXHDR(arg2);
4143 
4144  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4145  if ((cmp == 0) && (len1 != len2))
4146  cmp = (len1 < len2) ? -1 : 1;
4147 
4148  PG_FREE_IF_COPY(arg1, 0);
4149  PG_FREE_IF_COPY(arg2, 1);
4150 
4151  PG_RETURN_INT32(cmp);
4152 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:905
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ byteaeq()

Datum byteaeq ( PG_FUNCTION_ARGS  )

Definition at line 3989 of file varlena.c.

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

Referenced by gbt_byteaeq().

3990 {
3991  Datum arg1 = PG_GETARG_DATUM(0);
3992  Datum arg2 = PG_GETARG_DATUM(1);
3993  bool result;
3994  Size len1,
3995  len2;
3996 
3997  /*
3998  * We can use a fast path for unequal lengths, which might save us from
3999  * having to detoast one or both values.
4000  */
4001  len1 = toast_raw_datum_size(arg1);
4002  len2 = toast_raw_datum_size(arg2);
4003  if (len1 != len2)
4004  result = false;
4005  else
4006  {
4007  bytea *barg1 = DatumGetByteaPP(arg1);
4008  bytea *barg2 = DatumGetByteaPP(arg2);
4009 
4010  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4011  len1 - VARHDRSZ) == 0);
4012 
4013  PG_FREE_IF_COPY(barg1, 0);
4014  PG_FREE_IF_COPY(barg2, 1);
4015  }
4016 
4017  PG_RETURN_BOOL(result);
4018 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define VARHDRSZ
Definition: c.h:556
#define DatumGetByteaPP(X)
Definition: fmgr.h:285
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:806
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
size_t Size
Definition: c.h:467
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

Definition at line 4113 of file varlena.c.

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

Referenced by gbt_byteage().

4114 {
4115  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4116  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4117  int len1,
4118  len2;
4119  int cmp;
4120 
4121  len1 = VARSIZE_ANY_EXHDR(arg1);
4122  len2 = VARSIZE_ANY_EXHDR(arg2);
4123 
4124  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4125 
4126  PG_FREE_IF_COPY(arg1, 0);
4127  PG_FREE_IF_COPY(arg2, 1);
4128 
4129  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
4130 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:905
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ byteaGetBit()

Datum byteaGetBit ( PG_FUNCTION_ARGS  )

Definition at line 3435 of file varlena.c.

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

3436 {
3437  bytea *v = PG_GETARG_BYTEA_PP(0);
3438  int32 n = PG_GETARG_INT32(1);
3439  int byteNo,
3440  bitNo;
3441  int len;
3442  int byte;
3443 
3444  len = VARSIZE_ANY_EXHDR(v);
3445 
3446  if (n < 0 || n >= len * 8)
3447  ereport(ERROR,
3448  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3449  errmsg("index %d out of valid range, 0..%d",
3450  n, len * 8 - 1)));
3451 
3452  byteNo = n / 8;
3453  bitNo = n % 8;
3454 
3455  byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3456 
3457  if (byte & (1 << bitNo))
3458  PG_RETURN_INT32(1);
3459  else
3460  PG_RETURN_INT32(0);
3461 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define byte(x, n)
Definition: rijndael.c:68
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

Definition at line 3406 of file varlena.c.

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

3407 {
3408  bytea *v = PG_GETARG_BYTEA_PP(0);
3409  int32 n = PG_GETARG_INT32(1);
3410  int len;
3411  int byte;
3412 
3413  len = VARSIZE_ANY_EXHDR(v);
3414 
3415  if (n < 0 || n >= len)
3416  ereport(ERROR,
3417  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3418  errmsg("index %d out of valid range, 0..%d",
3419  n, len - 1)));
3420 
3421  byte = ((unsigned char *) VARDATA_ANY(v))[n];
3422 
3423  PG_RETURN_INT32(byte);
3424 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int errcode(int sqlerrcode)
Definition: elog.c:608
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
#define byte(x, n)
Definition: rijndael.c:68
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

Definition at line 4093 of file varlena.c.

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

Referenced by gbt_byteagt().

4094 {
4095  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4096  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4097  int len1,
4098  len2;
4099  int cmp;
4100 
4101  len1 = VARSIZE_ANY_EXHDR(arg1);
4102  len2 = VARSIZE_ANY_EXHDR(arg2);
4103 
4104  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4105 
4106  PG_FREE_IF_COPY(arg1, 0);
4107  PG_FREE_IF_COPY(arg2, 1);
4108 
4109  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
4110 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:905
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ byteain()

Datum byteain ( PG_FUNCTION_ARGS  )

Definition at line 277 of file varlena.c.

References ereport, errcode(), errmsg(), ERROR, hex_decode(), palloc(), PG_GETARG_CSTRING, PG_RETURN_BYTEA_P, SET_VARSIZE, VAL, VARDATA, and VARHDRSZ.

Referenced by CreateTrigger(), and string_to_datum().

278 {
279  char *inputText = PG_GETARG_CSTRING(0);
280  char *tp;
281  char *rp;
282  int bc;
283  bytea *result;
284 
285  /* Recognize hex input */
286  if (inputText[0] == '\\' && inputText[1] == 'x')
287  {
288  size_t len = strlen(inputText);
289 
290  bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */
291  result = palloc(bc);
292  bc = hex_decode(inputText + 2, len - 2, VARDATA(result));
293  SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
294 
295  PG_RETURN_BYTEA_P(result);
296  }
297 
298  /* Else, it's the traditional escaped style */
299  for (bc = 0, tp = inputText; *tp != '\0'; bc++)
300  {
301  if (tp[0] != '\\')
302  tp++;
303  else if ((tp[0] == '\\') &&
304  (tp[1] >= '0' && tp[1] <= '3') &&
305  (tp[2] >= '0' && tp[2] <= '7') &&
306  (tp[3] >= '0' && tp[3] <= '7'))
307  tp += 4;
308  else if ((tp[0] == '\\') &&
309  (tp[1] == '\\'))
310  tp += 2;
311  else
312  {
313  /*
314  * one backslash, not followed by another or ### valid octal
315  */
316  ereport(ERROR,
317  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
318  errmsg("invalid input syntax for type %s", "bytea")));
319  }
320  }
321 
322  bc += VARHDRSZ;
323 
324  result = (bytea *) palloc(bc);
325  SET_VARSIZE(result, bc);
326 
327  tp = inputText;
328  rp = VARDATA(result);
329  while (*tp != '\0')
330  {
331  if (tp[0] != '\\')
332  *rp++ = *tp++;
333  else if ((tp[0] == '\\') &&
334  (tp[1] >= '0' && tp[1] <= '3') &&
335  (tp[2] >= '0' && tp[2] <= '7') &&
336  (tp[3] >= '0' && tp[3] <= '7'))
337  {
338  bc = VAL(tp[1]);
339  bc <<= 3;
340  bc += VAL(tp[2]);
341  bc <<= 3;
342  *rp++ = bc + VAL(tp[3]);
343 
344  tp += 4;
345  }
346  else if ((tp[0] == '\\') &&
347  (tp[1] == '\\'))
348  {
349  *rp++ = '\\';
350  tp += 2;
351  }
352  else
353  {
354  /*
355  * We should never get here. The first pass should not allow it.
356  */
357  ereport(ERROR,
358  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
359  errmsg("invalid input syntax for type %s", "bytea")));
360  }
361  }
362 
363  PG_RETURN_BYTEA_P(result);
364 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:556
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
unsigned hex_decode(const char *src, unsigned len, char *dst)
Definition: encode.c:156
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
#define VAL(CH)
Definition: varlena.c:262
Definition: c.h:550
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

Definition at line 4073 of file varlena.c.

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

Referenced by gbt_byteale().

4074 {
4075  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4076  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4077  int len1,
4078  len2;
4079  int cmp;
4080 
4081  len1 = VARSIZE_ANY_EXHDR(arg1);
4082  len2 = VARSIZE_ANY_EXHDR(arg2);
4083 
4084  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4085 
4086  PG_FREE_IF_COPY(arg1, 0);
4087  PG_FREE_IF_COPY(arg2, 1);
4088 
4089  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
4090 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:905
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ bytealt()

Datum bytealt ( PG_FUNCTION_ARGS  )

Definition at line 4053 of file varlena.c.

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

Referenced by gbt_bytealt().

4054 {
4055  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4056  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4057  int len1,
4058  len2;
4059  int cmp;
4060 
4061  len1 = VARSIZE_ANY_EXHDR(arg1);
4062  len2 = VARSIZE_ANY_EXHDR(arg2);
4063 
4064  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4065 
4066  PG_FREE_IF_COPY(arg1, 0);
4067  PG_FREE_IF_COPY(arg2, 1);
4068 
4069  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
4070 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:905
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ byteane()

Datum byteane ( PG_FUNCTION_ARGS  )

Definition at line 4021 of file varlena.c.

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

4022 {
4023  Datum arg1 = PG_GETARG_DATUM(0);
4024  Datum arg2 = PG_GETARG_DATUM(1);
4025  bool result;
4026  Size len1,
4027  len2;
4028 
4029  /*
4030  * We can use a fast path for unequal lengths, which might save us from
4031  * having to detoast one or both values.
4032  */
4033  len1 = toast_raw_datum_size(arg1);
4034  len2 = toast_raw_datum_size(arg2);
4035  if (len1 != len2)
4036  result = true;
4037  else
4038  {
4039  bytea *barg1 = DatumGetByteaPP(arg1);
4040  bytea *barg2 = DatumGetByteaPP(arg2);
4041 
4042  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4043  len1 - VARHDRSZ) != 0);
4044 
4045  PG_FREE_IF_COPY(barg1, 0);
4046  PG_FREE_IF_COPY(barg2, 1);
4047  }
4048 
4049  PG_RETURN_BOOL(result);
4050 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define VARHDRSZ
Definition: c.h:556
#define DatumGetByteaPP(X)
Definition: fmgr.h:285
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:806
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
size_t Size
Definition: c.h:467
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 3138 of file varlena.c.

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

3139 {
3140  Datum str = PG_GETARG_DATUM(0);
3141 
3142  /* We need not detoast the input at all */
3144 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define VARHDRSZ
Definition: c.h:556
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:806
uintptr_t Datum
Definition: postgres.h:367

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 373 of file varlena.c.

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

Referenced by patternsel_common(), and pg_mcv_list_out().

374 {
375  bytea *vlena = PG_GETARG_BYTEA_PP(0);
376  char *result;
377  char *rp;
378 
380  {
381  /* Print hex format */
382  rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
383  *rp++ = '\\';
384  *rp++ = 'x';
385  rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
386  }
387  else if (bytea_output == BYTEA_OUTPUT_ESCAPE)
388  {
389  /* Print traditional escaped format */
390  char *vp;
391  int len;
392  int i;
393 
394  len = 1; /* empty string has 1 char */
395  vp = VARDATA_ANY(vlena);
396  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
397  {
398  if (*vp == '\\')
399  len += 2;
400  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
401  len += 4;
402  else
403  len++;
404  }
405  rp = result = (char *) palloc(len);
406  vp = VARDATA_ANY(vlena);
407  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
408  {
409  if (*vp == '\\')
410  {
411  *rp++ = '\\';
412  *rp++ = '\\';
413  }
414  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
415  {
416  int val; /* holds unprintable chars */
417 
418  val = *vp;
419  rp[0] = '\\';
420  rp[3] = DIG(val & 07);
421  val >>= 3;
422  rp[2] = DIG(val & 07);
423  val >>= 3;
424  rp[1] = DIG(val & 03);
425  rp += 4;
426  }
427  else
428  *rp++ = *vp;
429  }
430  }
431  else
432  {
433  elog(ERROR, "unrecognized bytea_output setting: %d",
434  bytea_output);
435  rp = result = NULL; /* keep compiler quiet */
436  }
437  *rp = '\0';
438  PG_RETURN_CSTRING(result);
439 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
unsigned hex_encode(const char *src, unsigned len, char *dst)
Definition: encode.c:126
#define ERROR
Definition: elog.h:43
int bytea_output
Definition: varlena.c:41
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228
int i
Definition: c.h:550
long val
Definition: informix.c:684
#define DIG(VAL)
Definition: varlena.c:263

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 3303 of file varlena.c.

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

3304 {
3305  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3306  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3307  int sp = PG_GETARG_INT32(2); /* substring start position */
3308  int sl = PG_GETARG_INT32(3); /* substring length */
3309 
3310  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3311 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3326
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
Definition: c.h:550

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3314 of file varlena.c.

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

3315 {
3316  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3317  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3318  int sp = PG_GETARG_INT32(2); /* substring start position */
3319  int sl;
3320 
3321  sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
3322  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3323 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3326
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 3362 of file varlena.c.

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

3363 {
3364  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3365  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3366  int pos;
3367  int px,
3368  p;
3369  int len1,
3370  len2;
3371  char *p1,
3372  *p2;
3373 
3374  len1 = VARSIZE_ANY_EXHDR(t1);
3375  len2 = VARSIZE_ANY_EXHDR(t2);
3376 
3377  if (len2 <= 0)
3378  PG_RETURN_INT32(1); /* result for empty pattern */
3379 
3380  p1 = VARDATA_ANY(t1);
3381  p2 = VARDATA_ANY(t2);
3382 
3383  pos = 0;
3384  px = (len1 - len2);
3385  for (p = 0; p <= px; p++)
3386  {
3387  if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
3388  {
3389  pos = p + 1;
3390  break;
3391  };
3392  p1++;
3393  };
3394 
3395  PG_RETURN_INT32(pos);
3396 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

Definition at line 445 of file varlena.c.

References buf, StringInfoData::cursor, StringInfoData::len, palloc(), PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_copymsgbytes(), SET_VARSIZE, VARDATA, and VARHDRSZ.

446 {
448  bytea *result;
449  int nbytes;
450 
451  nbytes = buf->len - buf->cursor;
452  result = (bytea *) palloc(nbytes + VARHDRSZ);
453  SET_VARSIZE(result, nbytes + VARHDRSZ);
454  pq_copymsgbytes(buf, VARDATA(result), nbytes);
455  PG_RETURN_BYTEA_P(result);
456 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:556
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
static char * buf
Definition: pg_test_fsync.c:67
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:530
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:550
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ byteasend()

Datum byteasend ( PG_FUNCTION_ARGS  )

Definition at line 464 of file varlena.c.

References PG_GETARG_BYTEA_P_COPY, and PG_RETURN_BYTEA_P.

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

465 {
466  bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
467 
468  PG_RETURN_BYTEA_P(vlena);
469 }
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:308
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
Definition: c.h:550

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 3504 of file varlena.c.

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

3505 {
3506  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3507  int32 n = PG_GETARG_INT32(1);
3508  int32 newBit = PG_GETARG_INT32(2);
3509  int len;
3510  int oldByte,
3511  newByte;
3512  int byteNo,
3513  bitNo;
3514 
3515  len = VARSIZE(res) - VARHDRSZ;
3516 
3517  if (n < 0 || n >= len * 8)
3518  ereport(ERROR,
3519  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3520  errmsg("index %d out of valid range, 0..%d",
3521  n, len * 8 - 1)));
3522 
3523  byteNo = n / 8;
3524  bitNo = n % 8;
3525 
3526  /*
3527  * sanity check!
3528  */
3529  if (newBit != 0 && newBit != 1)
3530  ereport(ERROR,
3531  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3532  errmsg("new bit must be 0 or 1")));
3533 
3534  /*
3535  * Update the byte.
3536  */
3537  oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3538 
3539  if (newBit == 0)
3540  newByte = oldByte & (~(1 << bitNo));
3541  else
3542  newByte = oldByte | (1 << bitNo);
3543 
3544  ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3545 
3546  PG_RETURN_BYTEA_P(res);
3547 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:556
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:308
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

Definition at line 3472 of file varlena.c.

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

3473 {
3474  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3475  int32 n = PG_GETARG_INT32(1);
3476  int32 newByte = PG_GETARG_INT32(2);
3477  int len;
3478 
3479  len = VARSIZE(res) - VARHDRSZ;
3480 
3481  if (n < 0 || n >= len)
3482  ereport(ERROR,
3483  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3484  errmsg("index %d out of valid range, 0..%d",
3485  n, len - 1)));
3486 
3487  /*
3488  * Now set the byte.
3489  */
3490  ((unsigned char *) VARDATA(res))[n] = newByte;
3491 
3492  PG_RETURN_BYTEA_P(res);
3493 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:556
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:308
int errcode(int sqlerrcode)
Definition: elog.c:608
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
signed int int32
Definition: c.h:347
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ charlen_to_bytelen()

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

Definition at line 757 of file varlena.c.

References pg_database_encoding_max_length(), and pg_mblen().

Referenced by appendStringInfoRegexpSubstr(), and replace_text_regexp().

758 {
760  {
761  /* Optimization for single-byte encodings */
762  return n;
763  }
764  else
765  {
766  const char *s;
767 
768  for (s = p; n > 0; n--)
769  s += pg_mblen(s);
770 
771  return s - p;
772  }
773 }
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802

◆ check_collation_set()

static void check_collation_set ( Oid  collid)
static

Definition at line 1453 of file varlena.c.

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

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

1454 {
1455  if (!OidIsValid(collid))
1456  {
1457  /*
1458  * This typically means that the parser could not resolve a conflict
1459  * of implicit collations, so report it that way.
1460  */
1461  ereport(ERROR,
1462  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1463  errmsg("could not determine which collation to use for string comparison"),
1464  errhint("Use the COLLATE clause to set the collation explicitly.")));
1465  }
1466 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
int errcode(int sqlerrcode)
Definition: elog.c:608
#define OidIsValid(objectId)
Definition: c.h:639
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ check_replace_text_has_escape_char()

static bool check_replace_text_has_escape_char ( const text replace_text)
static

Definition at line 4266 of file varlena.c.

References pg_database_encoding_max_length(), pg_mblen(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text_regexp().

4267 {
4268  const char *p = VARDATA_ANY(replace_text);
4269  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4270 
4272  {
4273  for (; p < p_end; p++)
4274  {
4275  if (*p == '\\')
4276  return true;
4277  }
4278  }
4279  else
4280  {
4281  for (; p < p_end; p += pg_mblen(p))
4282  {
4283  if (*p == '\\')
4284  return true;
4285  }
4286  }
4287 
4288  return false;
4289 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ concat_internal()

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

Definition at line 5214 of file varlena.c.

References appendStringInfoString(), array_to_text_internal(), Assert, build_concat_foutcache(), cstring_to_text_with_len(), StringInfoData::data, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, get_base_element_type(), get_fn_expr_argtype(), get_fn_expr_variadic(), i, initStringInfo(), StringInfoData::len, 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().

5216 {
5217  text *result;
5219  FmgrInfo *foutcache;
5220  bool first_arg = true;
5221  int i;
5222 
5223  /*
5224  * concat(VARIADIC some-array) is essentially equivalent to
5225  * array_to_text(), ie concat the array elements with the given separator.
5226  * So we just pass the case off to that code.
5227  */
5228  if (get_fn_expr_variadic(fcinfo->flinfo))
5229  {
5230  ArrayType *arr;
5231 
5232  /* Should have just the one argument */
5233  Assert(argidx == PG_NARGS() - 1);
5234 
5235  /* concat(VARIADIC NULL) is defined as NULL */
5236  if (PG_ARGISNULL(argidx))
5237  return NULL;
5238 
5239  /*
5240  * Non-null argument had better be an array. We assume that any call
5241  * context that could let get_fn_expr_variadic return true will have
5242  * checked that a VARIADIC-labeled parameter actually is an array. So
5243  * it should be okay to just Assert that it's an array rather than
5244  * doing a full-fledged error check.
5245  */
5247 
5248  /* OK, safe to fetch the array value */
5249  arr = PG_GETARG_ARRAYTYPE_P(argidx);
5250 
5251  /*
5252  * And serialize the array. We tell array_to_text to ignore null
5253  * elements, which matches the behavior of the loop below.
5254  */
5255  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5256  }
5257 
5258  /* Normal case without explicit VARIADIC marker */
5259  initStringInfo(&str);
5260 
5261  /* Get output function info, building it if first time through */
5262  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5263  if (foutcache == NULL)
5264  foutcache = build_concat_foutcache(fcinfo, argidx);
5265 
5266  for (i = argidx; i < PG_NARGS(); i++)
5267  {
5268  if (!PG_ARGISNULL(i))
5269  {
5271 
5272  /* add separator if appropriate */
5273  if (first_arg)
5274  first_arg = false;
5275  else
5276  appendStringInfoString(&str, sepstr);
5277 
5278  /* call the appropriate type output function, append the result */
5280  OutputFunctionCall(&foutcache[i], value));
5281  }
5282  }
5283 
5284  result = cstring_to_text_with_len(str.data, str.len);
5285  pfree(str.data);
5286 
5287  return result;
5288 }
Definition: fmgr.h:56
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
static struct @145 value
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1951
#define OidIsValid(objectId)
Definition: c.h:639
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
void pfree(void *pointer)
Definition: mcxt.c:1056
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4878
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * flinfo
Definition: fmgr.h:87
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:733
#define PG_NARGS()
Definition: fmgr.h:198
void * fn_extra
Definition: fmgr.h:64
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2599
int i
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5176
Definition: c.h:550

◆ cstring_to_text()

text* cstring_to_text ( const char *  s)

Definition at line 171 of file varlena.c.

References cstring_to_text_with_len().

Referenced by array_dims(), ASN1_STRING_to_text(), booltext(), brin_page_type(), 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_jsonb_path_all(), get_scalar(), hash_page_type(), hstore_to_json(), hstore_to_json_loose(), inet_abbrev(), initcap(), json_in(), json_typeof(), jsonb_typeof(), JsonbValueAsText(), lower(), md5_bytea(), md5_text(), metaphone(), name_bpchar(), name_text(), network_host(), network_show(), oidvectortypes(), pg_collation_actual_version(), pg_collation_for(), pg_crypt(), pg_current_logfile(), pg_describe_object(), pg_export_snapshot(), 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_stats_ext_mcvlist_items(), pg_tablespace_location(), pg_walfile_name(), 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(), SPI_sql_row_to_xmlelement(), split_text(), ssl_cipher(), ssl_version(), string_to_text(), text_substring(), textin(), timeofday(), to_hex32(), to_hex64(), tsquerytree(), txid_status(), unaccent_dict(), upper(), X509_NAME_to_text(), xml_encode_special_chars(), xml_in(), and xml_recv().

172 {
173  return cstring_to_text_with_len(s, strlen(s));
174 }
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183

◆ cstring_to_text_with_len()

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

Definition at line 183 of file varlena.c.

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

Referenced by array_to_json(), array_to_json_pretty(), array_to_text_internal(), build_regexp_match_result(), build_regexp_split_result(), compute_tsvector_stats(), concat_internal(), cstring_to_text(), cstring_to_xmltype(), do_text_output_multiline(), dotrim(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), ExecEvalXmlExpr(), executeDateTimeMethod(), executeLikeRegex(), 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_svals(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), json_build_array(), json_build_array_noargs(), json_build_object(), json_build_object_noargs(), 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(), replace_text(), replace_text_regexp(), row_to_json(), row_to_json_pretty(), serialize_deflist(), split_text(), ssl_extension_info(), string_agg_finalfn(), stringinfo_to_xmltype(), text_format(), text_left(), text_right(), text_to_array_internal(), textrecv(), to_json(), transform_json_string_values(), tsquerytree(), tsvector_to_array(), tsvector_unnest(), varchar(), varchar_input(), and xslt_process().

184 {
185  text *result = (text *) palloc(len + VARHDRSZ);
186 
187  SET_VARSIZE(result, len + VARHDRSZ);
188  memcpy(VARDATA(result), s, len);
189 
190  return result;
191 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:556
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:550
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ internal_text_pattern_compare()

static int internal_text_pattern_compare ( text arg1,
text arg2 
)
static

Definition at line 3013 of file varlena.c.

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().

3014 {
3015  int result;
3016  int len1,
3017  len2;
3018 
3019  len1 = VARSIZE_ANY_EXHDR(arg1);
3020  len2 = VARSIZE_ANY_EXHDR(arg2);
3021 
3022  result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3023  if (result != 0)
3024  return result;
3025  else if (len1 < len2)
3026  return -1;
3027  else if (len1 > len2)
3028  return 1;
3029  else
3030  return 0;
3031 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:905
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5104 of file varlena.c.

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

Referenced by bytea_string_agg_transfn(), and string_agg_transfn().

5105 {
5106  StringInfo state;
5107  MemoryContext aggcontext;
5108  MemoryContext oldcontext;
5109 
5110  if (!AggCheckCallContext(fcinfo, &aggcontext))
5111  {
5112  /* cannot be called directly because of internal-type argument */
5113  elog(ERROR, "string_agg_transfn called in non-aggregate context");
5114  }
5115 
5116  /*
5117  * Create state in aggregate context. It'll stay there across subsequent
5118  * calls.
5119  */
5120  oldcontext = MemoryContextSwitchTo(aggcontext);
5121  state = makeStringInfo();
5122  MemoryContextSwitchTo(oldcontext);
5123 
5124  return state;
5125 }
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ERROR
Definition: elog.h:43
ts_parserstate state
Definition: tsquery.c:81
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3571
#define elog(elevel,...)
Definition: elog.h:228

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3577 of file varlena.c.

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

Referenced by nameiclike(), and nameicnlike().

3578 {
3579  Name s = PG_GETARG_NAME(0);
3580 
3582 }
Definition: c.h:604
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
#define NameStr(name)
Definition: c.h:610
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ nameeqtext()

Datum nameeqtext ( PG_FUNCTION_ARGS  )

Definition at line 2816 of file varlena.c.

References check_collation_set(), 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().

2817 {
2818  Name arg1 = PG_GETARG_NAME(0);
2819  text *arg2 = PG_GETARG_TEXT_PP(1);
2820  size_t len1 = strlen(NameStr(*arg1));
2821  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2822  Oid collid = PG_GET_COLLATION();
2823  bool result;
2824 
2825  check_collation_set(collid);
2826 
2827  if (collid == C_COLLATION_OID)
2828  result = (len1 == len2 &&
2829  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2830  else
2831  result = (varstr_cmp(NameStr(*arg1), len1,
2832  VARDATA_ANY(arg2), len2,
2833  collid) == 0);
2834 
2835  PG_FREE_IF_COPY(arg2, 1);
2836 
2837  PG_RETURN_BOOL(result);
2838 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1482
static void check_collation_set(Oid collid)
Definition: varlena.c:1453
Definition: c.h:604
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:610
Definition: c.h:550
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ namefastcmp_c()

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

Definition at line 2199 of file varlena.c.

References DatumGetName, NAMEDATALEN, and NameStr.

Referenced by varstr_sortsupport().

2200 {
2201  Name arg1 = DatumGetName(x);
2202  Name arg2 = DatumGetName(y);
2203 
2204  return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2205 }
#define NAMEDATALEN
#define DatumGetName(X)
Definition: postgres.h:585
Definition: c.h:604
#define NameStr(name)
Definition: c.h:610

◆ namefastcmp_locale()

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

Definition at line 2242 of file varlena.c.

References DatumGetName, NameStr, and varstrfastcmp_locale().

Referenced by varstr_sortsupport().

2243 {
2244  Name arg1 = DatumGetName(x);
2245  Name arg2 = DatumGetName(y);
2246 
2247  return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)),
2248  NameStr(*arg2), strlen(NameStr(*arg2)),
2249  ssup);
2250 }
#define DatumGetName(X)
Definition: postgres.h:585
Definition: c.h:604
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2256
#define NameStr(name)
Definition: c.h:610

◆ namegetext()

Datum namegetext ( PG_FUNCTION_ARGS  )

Definition at line 2972 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2973 {
2975 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2947
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2916

◆ namegttext()

Datum namegttext ( PG_FUNCTION_ARGS  )

Definition at line 2966 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2967 {
2969 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2947
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2916

◆ nameletext()

Datum nameletext ( PG_FUNCTION_ARGS  )

Definition at line 2960 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2961 {
2963 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2947
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2916

◆ namelttext()

Datum namelttext ( PG_FUNCTION_ARGS  )

Definition at line 2954 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2955 {
2957 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2947
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2916

◆ namenetext()

Datum namenetext ( PG_FUNCTION_ARGS  )

Definition at line 2866 of file varlena.c.

References check_collation_set(), 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().

2867 {
2868  Name arg1 = PG_GETARG_NAME(0);
2869  text *arg2 = PG_GETARG_TEXT_PP(1);
2870  size_t len1 = strlen(NameStr(*arg1));
2871  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2872  Oid collid = PG_GET_COLLATION();
2873  bool result;
2874 
2875  check_collation_set(collid);
2876 
2877  if (collid == C_COLLATION_OID)
2878  result = !(len1 == len2 &&
2879  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2880  else
2881  result = !(varstr_cmp(NameStr(*arg1), len1,
2882  VARDATA_ANY(arg2), len2,
2883  collid) == 0);
2884 
2885  PG_FREE_IF_COPY(arg2, 1);
2886 
2887  PG_RETURN_BOOL(result);
2888 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1482
static void check_collation_set(Oid collid)
Definition: varlena.c:1453
Definition: c.h:604
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:610
Definition: c.h:550
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

Definition at line 5050 of file varlena.c.

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

5051 {
5053  int32 result;
5054  int typlen;
5055 
5056  /* On first call, get the input type's typlen, and save at *fn_extra */
5057  if (fcinfo->flinfo->fn_extra == NULL)
5058  {
5059  /* Lookup the datatype of the supplied argument */
5060  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5061 
5062  typlen = get_typlen(argtypeid);
5063  if (typlen == 0) /* should not happen */
5064  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5065 
5066  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5067  sizeof(int));
5068  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5069  }
5070  else
5071  typlen = *((int *) fcinfo->flinfo->fn_extra);
5072 
5073  if (typlen == -1)
5074  {
5075  /* varlena type, possibly toasted */
5076  result = toast_datum_size(value);
5077  }
5078  else if (typlen == -2)
5079  {
5080  /* cstring */
5081  result = strlen(DatumGetCString(value)) + 1;
5082  }
5083  else
5084  {
5085  /* ordinary fixed-width type */
5086  result = typlen;
5087  }
5088 
5089  PG_RETURN_INT32(result);
5090 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
static struct @145 value
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:347
Size toast_datum_size(Datum value)
Definition: detoast.c:862
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:566
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
uintptr_t Datum
Definition: postgres.h:367
int16 get_typlen(Oid typid)
Definition: lsyscache.c:1975
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:228

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

Definition at line 4191 of file varlena.c.

References appendBinaryStringInfo(), appendStringInfoText(), CHECK_FOR_INTERRUPTS, cstring_to_text_with_len(), StringInfoData::data, initStringInfo(), StringInfoData::len, 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 execute_extension_script().

4192 {
4193  text *src_text = PG_GETARG_TEXT_PP(0);
4194  text *from_sub_text = PG_GETARG_TEXT_PP(1);
4195  text *to_sub_text = PG_GETARG_TEXT_PP(2);
4196  int src_text_len;
4197  int from_sub_text_len;
4199  text *ret_text;
4200  int chunk_len;
4201  char *curr_ptr;
4202  char *start_ptr;
4204  bool found;
4205 
4206  src_text_len = VARSIZE_ANY_EXHDR(src_text);
4207  from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4208 
4209  /* Return unmodified source string if empty source or pattern */
4210  if (src_text_len < 1 || from_sub_text_len < 1)
4211  {
4212  PG_RETURN_TEXT_P(src_text);
4213  }
4214 
4215  text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4216 
4217  found = text_position_next(&state);
4218 
4219  /* When the from_sub_text is not found, there is nothing to do. */
4220  if (!found)
4221  {
4222  text_position_cleanup(&state);
4223  PG_RETURN_TEXT_P(src_text);
4224  }
4225  curr_ptr = text_position_get_match_ptr(&state);
4226  start_ptr = VARDATA_ANY(src_text);
4227 
4228  initStringInfo(&str);
4229 
4230  do
4231  {
4233 
4234  /* copy the data skipped over by last text_position_next() */
4235  chunk_len = curr_ptr - start_ptr;
4236  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4237 
4238  appendStringInfoText(&str, to_sub_text);
4239 
4240  start_ptr = curr_ptr + from_sub_text_len;
4241 
4242  found = text_position_next(&state);
4243  if (found)
4244  curr_ptr = text_position_get_match_ptr(&state);
4245  }
4246  while (found);
4247 
4248  /* copy trailing data */
4249  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4250  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4251 
4252  text_position_cleanup(&state);
4253 
4254  ret_text = cstring_to_text_with_len(str.data, str.len);
4255  pfree(str.data);
4256 
4257  PG_RETURN_TEXT_P(ret_text);
4258 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1285
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1418
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
void pfree(void *pointer)
Definition: mcxt.c:1056
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4177
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
ts_parserstate state
Definition: tsquery.c:81
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1447
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1156
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ replace_text_regexp()

text* replace_text_regexp ( text src_text,
void *  regexp,
text replace_text,
bool  glob 
)

Definition at line 4404 of file varlena.c.

References appendBinaryStringInfo(), appendStringInfoRegexpSubstr(), appendStringInfoText(), buf, charlen_to_bytelen(), CHECK_FOR_INTERRUPTS, check_replace_text_has_escape_char(), cstring_to_text_with_len(), StringInfoData::data, ereport, errcode(), errmsg(), ERROR, initStringInfo(), StringInfoData::len, palloc(), pfree(), pg_mb2wchar_with_len(), pg_regerror(), pg_regexec(), REG_NOMATCH, REG_OKAY, REGEXP_REPLACE_BACKREF_CNT, regmatch_t::rm_eo, regmatch_t::rm_so, VARDATA_ANY, VARSIZE_ANY, and VARSIZE_ANY_EXHDR.

Referenced by textregexreplace(), and textregexreplace_noopt().

4406 {
4407  text *ret_text;
4408  regex_t *re = (regex_t *) regexp;
4409  int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4412  pg_wchar *data;
4413  size_t data_len;
4414  int search_start;
4415  int data_pos;
4416  char *start_ptr;
4417  bool have_escape;
4418 
4419  initStringInfo(&buf);
4420 
4421  /* Convert data string to wide characters. */
4422  data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4423  data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4424 
4425  /* Check whether replace_text has escape char. */
4426  have_escape = check_replace_text_has_escape_char(replace_text);
4427 
4428  /* start_ptr points to the data_pos'th character of src_text */
4429  start_ptr = (char *) VARDATA_ANY(src_text);
4430  data_pos = 0;
4431 
4432  search_start = 0;
4433  while (search_start <= data_len)
4434  {
4435  int regexec_result;
4436 
4438 
4439  regexec_result = pg_regexec(re,
4440  data,
4441  data_len,
4442  search_start,
4443  NULL, /* no details */
4445  pmatch,
4446  0);
4447 
4448  if (regexec_result == REG_NOMATCH)
4449  break;
4450 
4451  if (regexec_result != REG_OKAY)
4452  {
4453  char errMsg[100];
4454 
4456  pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4457  ereport(ERROR,
4458  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4459  errmsg("regular expression failed: %s", errMsg)));
4460  }
4461 
4462  /*
4463  * Copy the text to the left of the match position. Note we are given
4464  * character not byte indexes.
4465  */
4466  if (pmatch[0].rm_so - data_pos > 0)
4467  {
4468  int chunk_len;
4469 
4470  chunk_len = charlen_to_bytelen(start_ptr,
4471  pmatch[0].rm_so - data_pos);
4472  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4473 
4474  /*
4475  * Advance start_ptr over that text, to avoid multiple rescans of
4476  * it if the replace_text contains multiple back-references.
4477  */
4478  start_ptr += chunk_len;
4479  data_pos = pmatch[0].rm_so;
4480  }
4481 
4482  /*
4483  * Copy the replace_text. Process back references when the
4484  * replace_text has escape characters.
4485  */
4486  if (have_escape)
4487  appendStringInfoRegexpSubstr(&buf, replace_text, pmatch,
4488  start_ptr, data_pos);
4489  else
4490  appendStringInfoText(&buf, replace_text);
4491 
4492  /* Advance start_ptr and data_pos over the matched text. */
4493  start_ptr += charlen_to_bytelen(start_ptr,
4494  pmatch[0].rm_eo - data_pos);
4495  data_pos = pmatch[0].rm_eo;
4496 
4497  /*
4498  * When global option is off, replace the first instance only.
4499  */
4500  if (!glob)
4501  break;
4502 
4503  /*
4504  * Advance search position. Normally we start the next search at the
4505  * end of the previous match; but if the match was of zero length, we
4506  * have to advance by one character, or we'd just find the same match
4507  * again.
4508  */
4509  search_start = data_pos;
4510  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4511  search_start++;
4512  }
4513 
4514  /*
4515  * Copy the text to the right of the last match.
4516  */
4517  if (data_pos < data_len)
4518  {
4519  int chunk_len;
4520 
4521  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4522  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4523  }
4524 
4525  ret_text = cstring_to_text_with_len(buf.data, buf.len);
4526  pfree(buf.data);
4527  pfree(data);
4528 
4529  return ret_text;
4530 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
regoff_t rm_so
Definition: regex.h:85
int errcode(int sqlerrcode)
Definition: elog.c:608
regoff_t rm_eo
Definition: regex.h:86
void pfree(void *pointer)
Definition: mcxt.c:1056
#define REG_OKAY
Definition: regex.h:137
#define ERROR
Definition: elog.h:43
static bool check_replace_text_has_escape_char(const text *replace_text)
Definition: varlena.c:4266
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:757
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4177
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
#define ereport(elevel, rest)
Definition: elog.h:141
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define REGEXP_REPLACE_BACKREF_CNT
Definition: varlena.c:4393
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:765
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4299
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:172
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define REG_NOMATCH
Definition: regex.h:138
Definition: c.h:550
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
Definition: regex.h:55

◆ rest_of_char_same()

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

Definition at line 5944 of file varlena.c.

Referenced by varstr_levenshtein().

5945 {
5946  while (len > 0)
5947  {
5948  len--;
5949  if (s1[len] != s2[len])
5950  return false;
5951  }
5952  return true;
5953 }
char * s1
char * s2

◆ split_text()

Datum split_text ( PG_FUNCTION_ARGS  )

Definition at line 4539 of file varlena.c.

References 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_setup(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

4540 {
4541  text *inputstring = PG_GETARG_TEXT_PP(0);
4542  text *fldsep = PG_GETARG_TEXT_PP(1);
4543  int fldnum = PG_GETARG_INT32(2);
4544  int inputstring_len;
4545  int fldsep_len;
4547  char *start_ptr;
4548  char *end_ptr;
4549  text *result_text;
4550  bool found;
4551 
4552  /* field number is 1 based */
4553  if (fldnum < 1)
4554  ereport(ERROR,
4555  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4556  errmsg("field position must be greater than zero")));
4557 
4558  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4559  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4560 
4561  /* return empty string for empty input string */
4562  if (inputstring_len < 1)
4564 
4565  /* empty field separator */
4566  if (fldsep_len < 1)
4567  {
4568  text_position_cleanup(&state);
4569  /* if first field, return input string, else empty string */
4570  if (fldnum == 1)
4571  PG_RETURN_TEXT_P(inputstring);
4572  else
4574  }
4575 
4576  text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4577 
4578  /* identify bounds of first field */
4579  start_ptr = VARDATA_ANY(inputstring);
4580  found = text_position_next(&state);
4581 
4582  /* special case if fldsep not found at all */
4583  if (!found)
4584  {
4585  text_position_cleanup(&state);
4586  /* if field 1 requested, return input string, else empty string */
4587  if (fldnum == 1)
4588  PG_RETURN_TEXT_P(inputstring);
4589  else
4591  }
4592  end_ptr = text_position_get_match_ptr(&state);
4593 
4594  while (found && --fldnum > 0)
4595  {
4596  /* identify bounds of next field */
4597  start_ptr = end_ptr + fldsep_len;
4598  found = text_position_next(&state);
4599  if (found)
4600  end_ptr = text_position_get_match_ptr(&state);
4601  }
4602 
4603  text_position_cleanup(&state);
4604 
4605  if (fldnum > 0)
4606  {
4607  /* N'th field separator not found */
4608  /* if last field requested, return it, else empty string */
4609  if (fldnum == 1)
4610  {
4611  int last_len = start_ptr - VARDATA_ANY(inputstring);
4612 
4613  result_text = cstring_to_text_with_len(start_ptr,
4614  inputstring_len - last_len);
4615  }
4616  else
4617  result_text = cstring_to_text("");
4618  }
4619  else
4620  {
4621  /* non-last field requested */
4622  result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4623  }
4624 
4625  PG_RETURN_TEXT_P(result_text);
4626 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int errcode(int sqlerrcode)
Definition: elog.c:608
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1285
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1418
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define ERROR
Definition: elog.h:43
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define ereport(elevel, rest)
Definition: elog.h:141
ts_parserstate state
Definition: tsquery.c:81
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1447
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
text * cstring_to_text(const char *s)
Definition: varlena.c:171
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1156
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ SplitDirectoriesString()

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

Definition at line 3779 of file varlena.c.

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

Referenced by load_libraries(), and PostmasterMain().

3781 {
3782  char *nextp = rawstring;
3783  bool done = false;
3784 
3785  *namelist = NIL;
3786 
3787  while (scanner_isspace(*nextp))
3788  nextp++; /* skip leading whitespace */
3789 
3790  if (*nextp == '\0')
3791  return true; /* allow empty string */
3792 
3793  /* At the top of the loop, we are at start of a new directory. */
3794  do
3795  {
3796  char *curname;
3797  char *endp;
3798 
3799  if (*nextp == '"')
3800  {
3801  /* Quoted name --- collapse quote-quote pairs */
3802  curname = nextp + 1;
3803  for (;;)
3804  {
3805  endp = strchr(nextp + 1, '"');
3806  if (endp == NULL)
3807  return false; /* mismatched quotes */
3808  if (endp[1] != '"')
3809  break; /* found end of quoted name */
3810  /* Collapse adjacent quotes into one quote, and look again */
3811  memmove(endp, endp + 1, strlen(endp));
3812  nextp = endp;
3813  }
3814  /* endp now points at the terminating quote */
3815  nextp = endp + 1;
3816  }
3817  else
3818  {
3819  /* Unquoted name --- extends to separator or end of string */
3820  curname = endp = nextp;
3821  while (*nextp && *nextp != separator)
3822  {
3823  /* trailing whitespace should not be included in name */
3824  if (!scanner_isspace(*nextp))
3825  endp = nextp + 1;
3826  nextp++;
3827  }
3828  if (curname == endp)
3829  return false; /* empty unquoted name not allowed */
3830  }
3831 
3832  while (scanner_isspace(*nextp))
3833  nextp++; /* skip trailing whitespace */
3834 
3835  if (*nextp == separator)
3836  {
3837  nextp++;
3838  while (scanner_isspace(*nextp))
3839  nextp++; /* skip leading whitespace for next */
3840  /* we expect another name, so done remains false */
3841  }
3842  else if (*nextp == '\0')
3843  done = true;
3844  else
3845  return false; /* invalid syntax */
3846 
3847  /* Now safe to overwrite separator with a null */
3848  *endp = '\0';
3849 
3850  /* Truncate path if it's overlength */
3851  if (strlen(curname) >= MAXPGPATH)
3852  curname[MAXPGPATH - 1] = '\0';
3853 
3854  /*
3855  * Finished isolating current name --- add it to list
3856  */
3857  curname = pstrdup(curname);
3858  canonicalize_path(curname);
3859  *namelist = lappend(*namelist, curname);
3860 
3861  /* Loop back if we didn't reach end of string */
3862  } while (!done);
3863 
3864  return true;
3865 }
#define NIL
Definition: pg_list.h:65
char * pstrdup(const char *in)
Definition: mcxt.c:1186
void canonicalize_path(char *path)
Definition: path.c:254
#define MAXPGPATH
#define memmove(d, s, c)
Definition: c.h:1261
List * lappend(List *list, void *datum)
Definition: list.c:322
bool scanner_isspace(char ch)
Definition: scansup.c:220

◆ SplitGUCList()

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

Definition at line 3900 of file varlena.c.

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

Referenced by dumpFunc(), and pg_get_functiondef().

3902 {
3903  char *nextp = rawstring;
3904  bool done = false;
3905 
3906  *namelist = NIL;
3907 
3908  while (scanner_isspace(*nextp))
3909  nextp++; /* skip leading whitespace */
3910 
3911  if (*nextp == '\0')
3912  return true; /* allow empty string */
3913 
3914  /* At the top of the loop, we are at start of a new identifier. */
3915  do
3916  {
3917  char *curname;
3918  char *endp;
3919 
3920  if (*nextp == '"')
3921  {
3922  /* Quoted name --- collapse quote-quote pairs */
3923  curname = nextp + 1;
3924  for (;;)
3925  {
3926  endp = strchr(nextp + 1, '"');
3927  if (endp == NULL)
3928  return false; /* mismatched quotes */
3929  if (endp[1] != '"')
3930  break; /* found end of quoted name */
3931  /* Collapse adjacent quotes into one quote, and look again */
3932  memmove(endp, endp + 1, strlen(endp));
3933  nextp = endp;
3934  }
3935  /* endp now points at the terminating quote */
3936  nextp = endp + 1;
3937  }
3938  else
3939  {
3940  /* Unquoted name --- extends to separator or whitespace */
3941  curname = nextp;
3942  while (*nextp && *nextp != separator &&
3943  !scanner_isspace(*nextp))
3944  nextp++;
3945  endp = nextp;
3946  if (curname == nextp)
3947  return false; /* empty unquoted name not allowed */
3948  }
3949 
3950  while (scanner_isspace(*nextp))
3951  nextp++; /* skip trailing whitespace */
3952 
3953  if (*nextp == separator)
3954  {
3955  nextp++;
3956  while (scanner_isspace(*nextp))
3957  nextp++; /* skip leading whitespace for next */
3958  /* we expect another name, so done remains false */
3959  }
3960  else if (*nextp == '\0')
3961  done = true;
3962  else
3963  return false; /* invalid syntax */
3964 
3965  /* Now safe to overwrite separator with a null */
3966  *endp = '\0';
3967 
3968  /*
3969  * Finished isolating current name --- add it to list
3970  */
3971  *namelist = lappend(*namelist, curname);
3972 
3973  /* Loop back if we didn't reach end of string */
3974  } while (!done);
3975 
3976  return true;
3977 }
#define NIL
Definition: pg_list.h:65
#define memmove(d, s, c)
Definition: c.h:1261
List * lappend(List *list, void *datum)
Definition: list.c:322
bool scanner_isspace(char ch)
Definition: scansup.c:220

◆ SplitIdentifierString()

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

Definition at line 3652 of file varlena.c.

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

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

3654 {
3655  char *nextp = rawstring;
3656  bool done = false;
3657 
3658  *namelist = NIL;
3659 
3660  while (scanner_isspace(*nextp))
3661  nextp++; /* skip leading whitespace */
3662 
3663  if (*nextp == '\0')
3664  return true; /* allow empty string */
3665 
3666  /* At the top of the loop, we are at start of a new identifier. */
3667  do
3668  {
3669  char *curname;
3670  char *endp;
3671 
3672  if (*nextp == '"')
3673  {
3674  /* Quoted name --- collapse quote-quote pairs, no downcasing */
3675  curname = nextp + 1;
3676  for (;;)
3677  {
3678  endp = strchr(nextp + 1, '"');
3679  if (endp == NULL)
3680  return false; /* mismatched quotes */
3681  if (endp[1] != '"')
3682  break; /* found end of quoted name */
3683  /* Collapse adjacent quotes into one quote, and look again */
3684  memmove(endp, endp + 1, strlen(endp));
3685  nextp = endp;
3686  }
3687  /* endp now points at the terminating quote */
3688  nextp = endp + 1;
3689  }
3690  else
3691  {
3692  /* Unquoted name --- extends to separator or whitespace */
3693  char *downname;
3694  int len;
3695 
3696  curname = nextp;
3697  while (*nextp && *nextp != separator &&
3698  !scanner_isspace(*nextp))
3699  nextp++;
3700  endp = nextp;
3701  if (curname == nextp)
3702  return false; /* empty unquoted name not allowed */
3703 
3704  /*
3705  * Downcase the identifier, using same code as main lexer does.
3706  *
3707  * XXX because we want to overwrite the input in-place, we cannot
3708  * support a downcasing transformation that increases the string
3709  * length. This is not a problem given the current implementation
3710  * of downcase_truncate_identifier, but we'll probably have to do
3711  * something about this someday.
3712  */
3713  len = endp - curname;
3714  downname = downcase_truncate_identifier(curname, len, false);
3715  Assert(strlen(downname) <= len);
3716  strncpy(curname, downname, len); /* strncpy is required here */
3717  pfree(downname);
3718  }
3719 
3720  while (scanner_isspace(*nextp))
3721  nextp++; /* skip trailing whitespace */
3722 
3723  if (*nextp == separator)
3724  {
3725  nextp++;
3726  while (scanner_isspace(*nextp))
3727  nextp++; /* skip leading whitespace for next */
3728  /* we expect another name, so done remains false */
3729  }
3730  else if (*nextp == '\0')
3731  done = true;
3732  else
3733  return false; /* invalid syntax */
3734 
3735  /* Now safe to overwrite separator with a null */
3736  *endp = '\0';
3737 
3738  /* Truncate name if it's overlength */
3739  truncate_identifier(curname, strlen(curname), false);
3740 
3741  /*
3742  * Finished isolating current name --- add it to list
3743  */
3744  *namelist = lappend(*namelist, curname);
3745 
3746  /* Loop back if we didn't reach end of string */
3747  } while (!done);
3748 
3749  return true;
3750 }
#define NIL
Definition: pg_list.h:65
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:130
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:186
void pfree(void *pointer)
Definition: mcxt.c:1056
#define memmove(d, s, c)
Definition: c.h:1261
List * lappend(List *list, void *datum)
Definition: list.c:322
bool scanner_isspace(char ch)
Definition: scansup.c:220
#define Assert(condition)
Definition: c.h:733

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 5154 of file varlena.c.

References AggCheckCallContext(), Assert, cstring_to_text_with_len(), StringInfoData::data, StringInfoData::len, PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, and PG_RETURN_TEXT_P.

5155 {
5156  StringInfo state;
5157 
5158  /* cannot be called directly because of internal-type argument */
5159  Assert(AggCheckCallContext(fcinfo, NULL));
5160 
5161  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5162 
5163  if (state != NULL)
5165  else
5166  PG_RETURN_NULL();
5167 }
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
ts_parserstate state
Definition: tsquery.c:81
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:733
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3571
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 5128 of file varlena.c.

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

5129 {
5130  StringInfo state;
5131 
5132  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5133 
5134  /* Append the value unless null. */
5135  if (!PG_ARGISNULL(1))
5136  {
5137  /* On the first time through, we ignore the delimiter. */
5138  if (state == NULL)
5139  state = makeStringAggState(fcinfo);
5140  else if (!PG_ARGISNULL(2))
5141  appendStringInfoText(state, PG_GETARG_TEXT_PP(2)); /* delimiter */
5142 
5143  appendStringInfoText(state, PG_GETARG_TEXT_PP(1)); /* value */
5144  }
5145 
5146  /*
5147  * The transition type for string_agg() is declared to be "internal",
5148  * which is a pass-by-value type the same size as a pointer.
5149  */
5150  PG_RETURN_POINTER(state);
5151 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4177
ts_parserstate state
Definition: tsquery.c:81
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5104

◆ text_catenate()

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

Definition at line 716 of file varlena.c.

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

Referenced by text_overlay(), and textcat().

717 {
718  text *result;
719  int len1,
720  len2,
721  len;
722  char *ptr;
723 
724  len1 = VARSIZE_ANY_EXHDR(t1);
725  len2 = VARSIZE_ANY_EXHDR(t2);
726 
727  /* paranoia ... probably should throw error instead? */
728  if (len1 < 0)
729  len1 = 0;
730  if (len2 < 0)
731  len2 = 0;
732 
733  len = len1 + len2 + VARHDRSZ;
734  result = (text *) palloc(len);
735 
736  /* Set size of result string... */
737  SET_VARSIZE(result, len);
738 
739  /* Fill data field of result string... */
740  ptr = VARDATA(result);
741  if (len1 > 0)
742  memcpy(ptr, VARDATA_ANY(t1), len1);
743  if (len2 > 0)
744  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
745 
746  return result;
747 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:556
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:550
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ text_cmp()

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

Definition at line 1698 of file varlena.c.

References 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().

1699 {
1700  char *a1p,
1701  *a2p;
1702  int len1,
1703  len2;
1704 
1705  a1p = VARDATA_ANY(arg1);
1706  a2p = VARDATA_ANY(arg2);
1707 
1708  len1 = VARSIZE_ANY_EXHDR(arg1);
1709  len2 = VARSIZE_ANY_EXHDR(arg2);
1710 
1711  return varstr_cmp(a1p, len1, a2p, len2, collid);
1712 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1482
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 5294 of file varlena.c.

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

5295 {
5296  text *result;
5297 
5298  result = concat_internal("", 0, fcinfo);
5299  if (result == NULL)
5300  PG_RETURN_NULL();
5301  PG_RETURN_TEXT_P(result);
5302 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5214
Definition: c.h:550
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5309 of file varlena.c.

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

5310 {
5311  char *sep;
5312  text *result;
5313 
5314  /* return NULL when separator is NULL */
5315  if (PG_ARGISNULL(0))
5316  PG_RETURN_NULL();
5318 
5319  result = concat_internal(sep, 1, fcinfo);
5320  if (result == NULL)
5321  PG_RETURN_NULL();
5322  PG_RETURN_TEXT_P(result);
5323 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5214
char * text_to_cstring(const text *t)
Definition: varlena.c:204
Definition: c.h:550
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

Definition at line 5430 of file varlena.c.

References ADVANCE_PARSE_POINTER, appendStringInfoCharMacro, arg, ARR_ELEMTYPE, Assert, cstring_to_text_with_len(), StringInfoData::data, DatumGetInt16, DatumGetInt32, deconstruct_array(), elog, ereport, errcode(), errhint(), errmsg(), ERROR, fmgr_info(), get_base_element_type(), get_fn_expr_argtype(), get_fn_expr_variadic(), get_typlenbyvalalign(), getTypeOutputInfo(), initStringInfo(), InvalidOid, StringInfoData::len, OidIsValid, OutputFunctionCall(), pfree(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_GETARG_TEXT_PP, 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().

5431 {
5432  text *fmt;
5434  const char *cp;
5435  const char *start_ptr;
5436  const char *end_ptr;
5437  text *result;
5438  int arg;
5439  bool funcvariadic;
5440  int nargs;
5441  Datum *elements = NULL;
5442  bool *nulls = NULL;
5443  Oid element_type = InvalidOid;
5444  Oid prev_type = InvalidOid;
5445  Oid prev_width_type = InvalidOid;
5446  FmgrInfo typoutputfinfo;
5447  FmgrInfo typoutputinfo_width;
5448 
5449  /* When format string is null, immediately return null */
5450  if (PG_ARGISNULL(0))
5451  PG_RETURN_NULL();
5452 
5453  /* If argument is marked VARIADIC, expand array into elements */
5454  if (get_fn_expr_variadic(fcinfo->flinfo))
5455  {
5456  ArrayType *arr;
5457  int16 elmlen;
5458  bool elmbyval;
5459  char elmalign;
5460  int nitems;
5461 
5462  /* Should have just the one argument */
5463  Assert(PG_NARGS() == 2);
5464 
5465  /* If argument is NULL, we treat it as zero-length array */
5466  if (PG_ARGISNULL(1))
5467  nitems = 0;
5468  else
5469  {
5470  /*
5471  * Non-null argument had better be an array. We assume that any
5472  * call context that could let get_fn_expr_variadic return true
5473  * will have checked that a VARIADIC-labeled parameter actually is
5474  * an array. So it should be okay to just Assert that it's an
5475  * array rather than doing a full-fledged error check.
5476  */
5478 
5479  /* OK, safe to fetch the array value */
5480  arr = PG_GETARG_ARRAYTYPE_P(1);
5481 
5482  /* Get info about array element type */
5483  element_type = ARR_ELEMTYPE(arr);
5484  get_typlenbyvalalign(element_type,
5485  &elmlen, &elmbyval, &elmalign);
5486 
5487  /* Extract all array elements */
5488  deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
5489  &elements, &nulls, &nitems);
5490  }
5491 
5492  nargs = nitems + 1;
5493  funcvariadic = true;
5494  }
5495  else
5496  {
5497  /* Non-variadic case, we'll process the arguments individually */
5498  nargs = PG_NARGS();
5499  funcvariadic = false;
5500  }
5501 
5502  /* Setup for main loop. */
5503  fmt = PG_GETARG_TEXT_PP(0);
5504  start_ptr = VARDATA_ANY(fmt);
5505  end_ptr = start_ptr + VARSIZE_ANY_EXHDR(fmt);
5506  initStringInfo(&str);
5507  arg = 1; /* next argument position to print */
5508 
5509  /* Scan format string, looking for conversion specifiers. */
5510  for (cp = start_ptr; cp < end_ptr; cp++)
5511  {
5512  int argpos;
5513  int widthpos;
5514  int flags;
5515  int width;
5516  Datum value;
5517  bool isNull;
5518  Oid typid;
5519 
5520  /*
5521  * If it's not the start of a conversion specifier, just copy it to
5522  * the output buffer.
5523  */
5524  if (*cp != '%')
5525  {
5526  appendStringInfoCharMacro(&str, *cp);
5527  continue;
5528  }
5529 
5530  ADVANCE_PARSE_POINTER(cp, end_ptr);
5531 
5532  /* Easy case: %% outputs a single % */
5533  if (*cp == '%')
5534  {
5535  appendStringInfoCharMacro(&str, *cp);
5536  continue;
5537  }
5538 
5539  /* Parse the optional portions of the format specifier */
5540  cp = text_format_parse_format(cp, end_ptr,
5541  &argpos, &widthpos,
5542  &flags, &width);
5543 
5544  /*
5545  * Next we should see the main conversion specifier. Whether or not
5546  * an argument position was present, it's known that at least one
5547  * character remains in the string at this point. Experience suggests
5548  * that it's worth checking that that character is one of the expected
5549  * ones before we try to fetch arguments, so as to produce the least
5550  * confusing response to a mis-formatted specifier.
5551  */
5552  if (strchr("sIL", *cp) == NULL)
5553  ereport(ERROR,
5554  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5555  errmsg("unrecognized format() type specifier \"%c\"",
5556  *cp),
5557  errhint("For a single \"%%\" use \"%%%%\".")));
5558 
5559  /* If indirect width was specified, get its value */
5560  if (widthpos >= 0)
5561  {
5562  /* Collect the specified or next argument position */
5563  if (widthpos > 0)
5564  arg = widthpos;
5565  if (arg >= nargs)
5566  ereport(ERROR,
5567  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5568  errmsg("too few arguments for format()")));
5569 
5570  /* Get the value and type of the selected argument */
5571  if (!funcvariadic)
5572  {
5573  value = PG_GETARG_DATUM(arg);
5574  isNull = PG_ARGISNULL(arg);
5575  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5576  }
5577  else
5578  {
5579  value = elements[arg - 1];
5580  isNull = nulls[arg - 1];
5581  typid = element_type;
5582  }
5583  if (!OidIsValid(typid))
5584  elog(ERROR, "could not determine data type of format() input");
5585 
5586  arg++;
5587 
5588  /* We can treat NULL width the same as zero */
5589  if (isNull)
5590  width = 0;
5591  else if (typid == INT4OID)
5592  width = DatumGetInt32(value);
5593  else if (typid == INT2OID)
5594  width = DatumGetInt16(value);
5595  else
5596  {
5597  /* For less-usual datatypes, convert to text then to int */
5598  char *str;
5599 
5600  if (typid != prev_width_type)
5601  {
5602  Oid typoutputfunc;
5603  bool typIsVarlena;
5604 
5605  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5606  fmgr_info(typoutputfunc, &typoutputinfo_width);
5607  prev_width_type = typid;
5608  }
5609 
5610  str = OutputFunctionCall(&typoutputinfo_width, value);
5611 
5612  /* pg_strtoint32 will complain about bad data or overflow */
5613  width = pg_strtoint32(str);
5614 
5615  pfree(str);
5616  }
5617  }
5618 
5619  /* Collect the specified or next argument position */
5620  if (argpos > 0)
5621  arg = argpos;
5622  if (arg >= nargs)
5623  ereport(ERROR,
5624  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5625  errmsg("too few arguments for format()")));
5626 
5627  /* Get the value and type of the selected argument */
5628  if (!funcvariadic)
5629  {
5630  value = PG_GETARG_DATUM(arg);
5631  isNull = PG_ARGISNULL(arg);
5632  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5633  }
5634  else
5635  {
5636  value = elements[arg - 1];
5637  isNull = nulls[arg - 1];
5638  typid = element_type;
5639  }
5640  if (!OidIsValid(typid))
5641  elog(ERROR, "could not determine data type of format() input");
5642 
5643  arg++;
5644 
5645  /*
5646  * Get the appropriate typOutput function, reusing previous one if
5647  * same type as previous argument. That's particularly useful in the
5648  * variadic-array case, but often saves work even for ordinary calls.
5649  */
5650  if (typid != prev_type)
5651  {
5652  Oid typoutputfunc;
5653  bool typIsVarlena;
5654 
5655  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5656  fmgr_info(typoutputfunc, &typoutputfinfo);
5657  prev_type = typid;
5658  }
5659 
5660  /*
5661  * And now we can format the value.
5662  */
5663  switch (*cp)
5664  {
5665  case 's':
5666  case 'I':
5667  case 'L':
5668  text_format_string_conversion(&str, *cp, &typoutputfinfo,
5669  value, isNull,
5670  flags, width);
5671  break;
5672  default:
5673  /* should not get here, because of previous check */
5674  ereport(ERROR,
5675  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5676  errmsg("unrecognized format() type specifier \"%c\"",
5677  *cp),
5678  errhint("For a single \"%%\" use \"%%%%\".")));
5679  break;
5680  }
5681  }
5682 
5683  /* Don't need deconstruct_array results anymore. */
5684  if (elements != NULL)
5685  pfree(elements);
5686  if (nulls != NULL)
5687  pfree(nulls);
5688 
5689  /* Generate results. */
5690  result = cstring_to_text_with_len(str.data, str.len);
5691  pfree(str.data);
5692 
5693  PG_RETURN_TEXT_P(result);
5694 }
signed short int16
Definition: c.h:346
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5417
Definition: fmgr.h:56
int errhint(const char *fmt,...)
Definition: elog.c:1071
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define DatumGetInt32(X)
Definition: postgres.h:472
static void text_format_string_conversion(StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
Definition: varlena.c:5833
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2049
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
static struct @145 value
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1951
int errcode(int sqlerrcode)
Definition: elog.c:608
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:639
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1817
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:124
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define DatumGetInt16(X)
Definition: postgres.h:444
#define ereport(elevel, rest)
Definition: elog.h:141
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
#define Assert(condition)
Definition: c.h:733
#define PG_NARGS()
Definition: fmgr.h:198
int32 pg_strtoint32(const char *s)
Definition: numutils.c:199
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3461
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2599
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
void * arg
Definition: c.h:550
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:5756
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ text_format_append_string()

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

Definition at line 5882 of file varlena.c.

References appendStringInfoSpaces(), appendStringInfoString(), ereport, errcode(), errmsg(), ERROR, pg_mbstrlen(), and TEXT_FORMAT_FLAG_MINUS.

Referenced by text_format_string_conversion().

5884 {
5885  bool align_to_left = false;
5886  int len;
5887 
5888  /* fast path for typical easy case */
5889  if (width == 0)
5890  {
5892  return;
5893  }
5894 
5895  if (width < 0)
5896  {
5897  /* Negative width: implicit '-' flag, then take absolute value */
5898  align_to_left = true;
5899  /* -INT_MIN is undefined */
5900  if (width <= INT_MIN)
5901  ereport(ERROR,
5902  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5903  errmsg("number is out of range")));
5904  width = -width;
5905  }
5906  else if (flags & TEXT_FORMAT_FLAG_MINUS)
5907  align_to_left = true;
5908 
5909  len = pg_mbstrlen(str);
5910  if (align_to_left)
5911  {
5912  /* left justify */
5914  if (len < width)
5915  appendStringInfoSpaces(buf, width - len);
5916  }
5917  else
5918  {
5919  /* right justify */
5920  if (len < width)
5921  appendStringInfoSpaces(buf, width - len);
5923  }
5924 }
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:206
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:816
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5415

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 5934 of file varlena.c.

References text_format().

5935 {
5936  return text_format(fcinfo);
5937 }
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5430

◆ text_format_parse_digits()

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

Definition at line 5707 of file varlena.c.

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

Referenced by text_format_parse_format().

5708 {
5709  bool found = false;
5710  const char *cp = *ptr;
5711  int val = 0;
5712 
5713  while (*cp >= '0' && *cp <= '9')
5714  {
5715  int8 digit = (*cp - '0');
5716 
5717  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5718  unlikely(pg_add_s32_overflow(val, digit, &val)))
5719  ereport(ERROR,
5720  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5721  errmsg("number is out of range")));
5722  ADVANCE_PARSE_POINTER(cp, end_ptr);
5723  found = true;
5724  }
5725 
5726  *ptr = cp;
5727  *value = val;
5728 
5729  return found;
5730 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5417
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140
static struct @145 value
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
signed char int8
Definition: c.h:345
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define unlikely(x)
Definition: c.h:208
long val
Definition: informix.c:684

◆ 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 5756 of file varlena.c.

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

Referenced by text_format().

5759 {
5760  const char *cp = start_ptr;
5761  int n;
5762 
5763  /* set defaults for output parameters */
5764  *argpos = -1;
5765  *widthpos = -1;
5766  *flags = 0;
5767  *width = 0;
5768 
5769  /* try to identify first number */
5770  if (text_format_parse_digits(&cp, end_ptr, &n))
5771  {
5772  if (*cp != '$')
5773  {
5774  /* Must be just a width and a type, so we're done */
5775  *width = n;
5776  return cp;
5777  }
5778  /* The number was argument position */
5779  *argpos = n;
5780  /* Explicit 0 for argument index is immediately refused */
5781  if (n == 0)
5782  ereport(ERROR,
5783  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5784  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5785  ADVANCE_PARSE_POINTER(cp, end_ptr);
5786  }
5787 
5788  /* Handle flags (only minus is supported now) */
5789  while (*cp == '-')
5790  {
5791  *flags |= TEXT_FORMAT_FLAG_MINUS;
5792  ADVANCE_PARSE_POINTER(cp, end_ptr);
5793  }
5794 
5795  if (*cp == '*')
5796  {
5797  /* Handle indirect width */
5798  ADVANCE_PARSE_POINTER(cp, end_ptr);
5799  if (text_format_parse_digits(&cp, end_ptr, &n))
5800  {
5801  /* number in this position must be closed by $ */
5802  if (*cp != '$')
5803  ereport(ERROR,
5804  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5805  errmsg("width argument position must be ended by \"$\"")));
5806  /* The number was width argument position */
5807  *widthpos = n;
5808  /* Explicit 0 for argument index is immediately refused */
5809  if (n == 0)
5810  ereport(ERROR,
5811  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5812  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5813  ADVANCE_PARSE_POINTER(cp, end_ptr);
5814  }
5815  else
5816  *widthpos = 0; /* width's argument position is unspecified */
5817  }
5818  else
5819  {
5820  /* Check for direct width specification */
5821  if (text_format_parse_digits(&cp, end_ptr, &n))
5822  *width = n;
5823  }
5824 
5825  /* cp should now be pointing at type character */
5826  return cp;
5827 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5417
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:5707
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5415

◆ 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 5833 of file varlena.c.

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

Referenced by text_format().

5837 {
5838  char *str;
5839 
5840  /* Handle NULL arguments before trying to stringify the value. */
5841  if (isNull)
5842  {
5843  if (conversion == 's')
5844  text_format_append_string(buf, "", flags, width);
5845  else if (conversion == 'L')
5846  text_format_append_string(buf, "NULL", flags, width);
5847  else if (conversion == 'I')
5848  ereport(ERROR,
5849  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5850  errmsg("null values cannot be formatted as an SQL identifier")));
5851  return;
5852  }
5853 
5854  /* Stringify. */
5855  str = OutputFunctionCall(typOutputInfo, value);
5856 
5857  /* Escape. */
5858  if (conversion == 'I')
5859  {
5860  /* quote_identifier may or may not allocate a new string. */
5861  text_format_append_string(buf, quote_identifier(str), flags, width);
5862  }
5863  else if (conversion == 'L')
5864  {
5865  char *qstr = quote_literal_cstr(str);
5866 
5867  text_format_append_string(buf, qstr, flags, width);
5868  /* quote_literal_cstr() always allocates a new string */
5869  pfree(qstr);
5870  }
5871  else
5872  text_format_append_string(buf, str, flags, width);
5873 
5874  /* Cleanup. */
5875  pfree(str);
5876 }
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:102
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10626
static struct @145 value
int errcode(int sqlerrcode)
Definition: elog.c:608
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:5882
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

Definition at line 1870 of file varlena.c.

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

Referenced by gbt_textge().

1871 {
1872  text *arg1 = PG_GETARG_TEXT_PP(0);
1873  text *arg2 = PG_GETARG_TEXT_PP(1);
1874  bool result;
1875 
1876  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1877 
1878  PG_FREE_IF_COPY(arg1, 0);
1879  PG_FREE_IF_COPY(arg2, 1);
1880 
1881  PG_RETURN_BOOL(result);
1882 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1698
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

Definition at line 1855 of file varlena.c.

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

Referenced by gbt_textgt().

1856 {
1857  text *arg1 = PG_GETARG_TEXT_PP(0);
1858  text *arg2 = PG_GETARG_TEXT_PP(1);
1859  bool result;
1860 
1861  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1862 
1863  PG_FREE_IF_COPY(arg1, 0);
1864  PG_FREE_IF_COPY(arg2, 1);
1865 
1866  PG_RETURN_BOOL(result);
1867 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1698
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_isequal()

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

Definition at line 4632 of file varlena.c.

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

Referenced by text_to_array_internal().

4633 {
4635  collid,
4636  PointerGetDatum(txt1),
4637  PointerGetDatum(txt2)));
4638 }
#define PointerGetDatum(X)
Definition: postgres.h:556
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1723
#define DatumGetBool(X)
Definition: postgres.h:393
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:813

◆ text_larger()

Datum text_larger ( PG_FUNCTION_ARGS  )

Definition at line 2787 of file varlena.c.

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

2788 {
2789  text *arg1 = PG_GETARG_TEXT_PP(0);
2790  text *arg2 = PG_GETARG_TEXT_PP(1);
2791  text *result;
2792 
2793  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2794 
2795  PG_RETURN_TEXT_P(result);
2796 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1698
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
Definition: c.h:550

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

Definition at line 1840 of file varlena.c.

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

Referenced by gbt_textle().

1841 {
1842  text *arg1 = PG_GETARG_TEXT_PP(0);
1843  text *arg2 = PG_GETARG_TEXT_PP(1);
1844  bool result;
1845 
1846  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1847 
1848  PG_FREE_IF_COPY(arg1, 0);
1849  PG_FREE_IF_COPY(arg2, 1);
1850 
1851  PG_RETURN_BOOL(result);
1852 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1698
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

Definition at line 5330 of file varlena.c.

References cstring_to_text_with_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.

5331 {
5332  int n = PG_GETARG_INT32(1);
5333 
5334  if (n < 0)
5335  {
5336  text *str = PG_GETARG_TEXT_PP(0);
5337  const char *p = VARDATA_ANY(str);
5338  int len = VARSIZE_ANY_EXHDR(str);
5339  int rlen;
5340 
5341  n = pg_mbstrlen_with_len(p, len) + n;
5342  rlen = pg_mbcharcliplen(p, len, n);
5344  }
5345  else
5347 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:904
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:836
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:836
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550

◆ text_length()

static int32 text_length ( Datum  str)
static

Definition at line 662 of file varlena.c.

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

Referenced by textlen(), and textoverlay_no_len().

663 {
664  /* fastpath when max encoding length is one */
667  else
668  {
669  text *t = DatumGetTextPP(str);
670 
672  VARSIZE_ANY_EXHDR(t)));
673  }
674 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARHDRSZ
Definition: c.h:556
#define DatumGetTextPP(X)
Definition: fmgr.h:286
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:836
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:806
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:550

◆ text_lt()

Datum text_lt ( PG_FUNCTION_ARGS  )

Definition at line 1825 of file varlena.c.

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

Referenced by gbt_textlt().

1826 {
1827  text *arg1 = PG_GETARG_TEXT_PP(0);
1828  text *arg2 = PG_GETARG_TEXT_PP(1);
1829  bool result;
1830 
1831  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
1832 
1833  PG_FREE_IF_COPY(arg1, 0);
1834  PG_FREE_IF_COPY(arg2, 1);
1835 
1836  PG_RETURN_BOOL(result);
1837 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1698
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_name()

Datum text_name ( PG_FUNCTION_ARGS  )

Definition at line 3554 of file varlena.c.

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

3555 {
3556  text *s = PG_GETARG_TEXT_PP(0);
3557  Name result;
3558  int len;
3559 
3560  len = VARSIZE_ANY_EXHDR(s);
3561 
3562  /* Truncate oversize input */
3563  if (len >= NAMEDATALEN)
3564  len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1);
3565 
3566  /* We use palloc0 here to ensure result is zero-padded */
3567  result = (Name) palloc0(NAMEDATALEN);
3568  memcpy(NameStr(*result), VARDATA_ANY(s), len);
3569 
3570  PG_RETURN_NAME(result);
3571 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define NAMEDATALEN
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:862
Definition: c.h:604
void * palloc0(Size size)
Definition: mcxt.c:980
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:610
Definition: c.h:550
NameData * Name
Definition: c.h:608
#define PG_RETURN_NAME(x)
Definition: fmgr.h:353

◆ text_overlay()

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

Definition at line 1056 of file varlena.c.

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

Referenced by textoverlay(), and textoverlay_no_len().

1057 {
1058  text *result;
1059  text *s1;
1060  text *s2;
1061  int sp_pl_sl;
1062 
1063  /*
1064  * Check for possible integer-overflow cases. For negative sp, throw a
1065  * "substring length" error because that's what should be expected
1066  * according to the spec's definition of OVERLAY().
1067  */
1068  if (sp <= 0)
1069  ereport(ERROR,
1070  (errcode(ERRCODE_SUBSTRING_ERROR),
1071  errmsg("negative substring length not allowed")));
1072  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
1073  ereport(ERROR,
1074  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1075  errmsg("integer out of range")));
1076 
1077  s1 = text_substring(PointerGetDatum(t1), 1, sp - 1, false);
1078  s2 = text_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
1079  result = text_catenate(s1, t2);
1080  result = text_catenate(result, s2);
1081 
1082  return result;
1083 }
#define PointerGetDatum(X)
Definition: postgres.h:556
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
char * s1
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:836
static text * text_catenate(text *t1, text *t2)
Definition: varlena.c:716
#define ereport(elevel, rest)
Definition: elog.h:141
char * s2
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:822
Definition: c.h:550

◆ text_pattern_ge()

Datum text_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 3067 of file varlena.c.

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

3068 {
3069  text *arg1 = PG_GETARG_TEXT_PP(0);
3070  text *arg2 = PG_GETARG_TEXT_PP(1);
3071  int result;
3072 
3073  result = internal_text_pattern_compare(arg1, arg2);
3074 
3075  PG_FREE_IF_COPY(arg1, 0);
3076  PG_FREE_IF_COPY(arg2, 1);
3077 
3078  PG_RETURN_BOOL(result >= 0);
3079 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3013
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_pattern_gt()

Datum text_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 3083 of file varlena.c.

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

3084 {
3085  text *arg1 = PG_GETARG_TEXT_PP(0);
3086  text *arg2 = PG_GETARG_TEXT_PP(1);
3087  int result;
3088 
3089  result = internal_text_pattern_compare(arg1, arg2);
3090 
3091  PG_FREE_IF_COPY(arg1, 0);
3092  PG_FREE_IF_COPY(arg2, 1);
3093 
3094  PG_RETURN_BOOL(result > 0);
3095 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3013
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_pattern_le()

Datum text_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 3051 of file varlena.c.

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

3052 {
3053  text *arg1 = PG_GETARG_TEXT_PP(0);
3054  text *arg2 = PG_GETARG_TEXT_PP(1);
3055  int result;
3056 
3057  result = internal_text_pattern_compare(arg1, arg2);
3058 
3059  PG_FREE_IF_COPY(arg1, 0);
3060  PG_FREE_IF_COPY(arg2, 1);
3061 
3062  PG_RETURN_BOOL(result <= 0);
3063 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3013
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_pattern_lt()

Datum text_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 3035 of file varlena.c.

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

3036 {
3037  text *arg1 = PG_GETARG_TEXT_PP(0);
3038  text *arg2 = PG_GETARG_TEXT_PP(1);
3039  int result;
3040 
3041  result = internal_text_pattern_compare(arg1, arg2);
3042 
3043  PG_FREE_IF_COPY(arg1, 0);
3044  PG_FREE_IF_COPY(arg2, 1);
3045 
3046  PG_RETURN_BOOL(result < 0);
3047 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3013
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:550

◆ text_position()

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

Definition at line 1116 of file varlena.c.

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

Referenced by textpos().

1117 {
1119  int result;
1120 
1121  /* Empty needle always matches at position 1 */
1122  if (VARSIZE_ANY_EXHDR(t2) < 1)
1123  return 1;
1124 
1125  /* Otherwise, can't match if haystack is shorter than needle */
1126  if (VARSIZE_ANY_EXHDR(t1) < VARSIZE_ANY_EXHDR(t2))
1127  return 0;
1128 
1129  text_position_setup(t1, t2, collid, &state);
1130  if (!text_position_next(&state))
1131  result = 0;
1132  else
1133  result = text_position_get_match_pos(&state);
1134  text_position_cleanup(&state);
1135  return result;
1136 }
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1285
static int text_position_get_match_pos(TextPositionState *state)
Definition: varlena.c:1429
ts_parserstate state
Definition: tsquery.c:81
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1447
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1156
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ text_position_cleanup()

static void text_position_cleanup ( TextPositionState state)
static

Definition at line 1447 of file varlena.c.

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

1448 {
1449  /* no cleanup needed */
1450 }

◆ text_position_get_match_pos()

static int text_position_get_match_pos ( TextPositionState state)
static

Definition at line 1429 of file varlena.c.

References Assert, TextPositionState::is_multibyte, TextPositionState::last_match, pg_mblen(), TextPositionState::refpoint, TextPositionState::refpos, and TextPositionState::str1.

Referenced by text_position().

1430 {
1431  if (!state->is_multibyte)
1432  return state->last_match - state->str1 + 1;
1433  else
1434  {
1435  /* Convert the byte position to char position. */
1436  while (state->refpoint < state->last_match)
1437  {
1438  state->refpoint += pg_mblen(state->refpoint);
1439  state->refpos++;
1440  }
1441  Assert(state->refpoint == state->last_match);
1442  return state->refpos + 1;
1443  }
1444 }
char * refpoint
Definition: varlena.c:71
char * last_match
Definition: varlena.c:63
bool is_multibyte
Definition: varlena.c:51
#define Assert(condition)
Definition: c.h:733
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802

◆ text_position_get_match_ptr()

static char * text_position_get_match_ptr ( TextPositionState state)
static

Definition at line 1418 of file varlena.c.

References TextPositionState::last_match.

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

1419 {
1420  return state->last_match;
1421 }
char * last_match
Definition: varlena.c:63

◆ text_position_next()

static bool text_position_next ( TextPositionState state)
static

Definition at line 1285 of file varlena.c.

References Assert, TextPositionState::is_multibyte_char_in_char, TextPositionState::last_match, TextPositionState::len2, pg_mblen(), TextPositionState::refpoint, TextPositionState::refpos, TextPositionState::str1, and text_position_next_internal().

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

1286 {
1287  int needle_len = state->len2;
1288  char *start_ptr;
1289  char *matchptr;
1290 
1291  if (needle_len <= 0)
1292  return false; /* result for empty pattern */
1293 
1294  /* Start from the point right after the previous match. */
1295  if (state->last_match)
1296  start_ptr = state->last_match + needle_len;
1297  else
1298  start_ptr = state->str1;
1299 
1300 retry:
1301  matchptr = text_position_next_internal(start_ptr, state);
1302 
1303  if (!matchptr)
1304  return false;
1305 
1306  /*
1307  * Found a match for the byte sequence. If this is a multibyte encoding,
1308  * where one character's byte sequence can appear inside a longer
1309  * multi-byte character, we need to verify that the match was at a
1310  * character boundary, not in the middle of a multi-byte character.
1311  */
1312  if (state->is_multibyte_char_in_char)
1313  {
1314  /* Walk one character at a time, until we reach the match. */
1315 
1316  /* the search should never move backwards. */
1317  Assert(state->refpoint <= matchptr);
1318 
1319  while (state->refpoint < matchptr)
1320  {
1321  /* step to next character. */
1322  state->refpoint += pg_mblen(state->refpoint);
1323  state->refpos++;
1324 
1325  /*
1326  * If we stepped over the match's start position, then it was a
1327  * false positive, where the byte sequence appeared in the middle
1328  * of a multi-byte character. Skip it, and continue the search at
1329  * the next character boundary.
1330  */
1331  if (state->refpoint > matchptr)
1332  {
1333  start_ptr = state->refpoint;
1334  goto retry;
1335  }
1336  }
1337  }
1338 
1339  state->last_match = matchptr;
1340  return true;
1341 }
char * refpoint
Definition: varlena.c:71
char * last_match
Definition: varlena.c:63
static char * text_position_next_internal(char *start_ptr, TextPositionState *state)
Definition: varlena.c:1349
#define Assert(condition)
Definition: c.h:733
int pg_mblen(const char *mbstr)
Definition: mbutils.c:802
bool is_multibyte_char_in_char
Definition: varlena.c:52

◆ text_position_next_internal()

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

Definition at line 1349 of file varlena.c.

References Assert, TextPositionState::len1, TextPositionState::len2, TextPositionState::skiptable, TextPositionState::skiptablemask, TextPositionState::str1, and TextPositionState::str2.

Referenced by text_position_next().

1350 {
1351  int haystack_len = state->len1;
1352  int needle_len = state->len2;
1353  int skiptablemask = state->skiptablemask;
1354  const char *haystack = state->str1;
1355  const char *needle = state->str2;
1356  const char *haystack_end = &haystack[haystack_len];
1357  const char *hptr;
1358 
1359  Assert(start_ptr >= haystack && start_ptr <= haystack_end);
1360 
1361  if (needle_len == 1)
1362  {
1363  /* No point in using B-M-H for a one-character needle */
1364  char nchar = *needle;
1365 
1366  hptr = start_ptr;
1367  while (hptr < haystack_end)
1368  {
1369  if (*hptr == nchar)
1370  return (char *) hptr;
1371  hptr++;
1372  }
1373  }
1374  else
1375  {
1376  const char *needle_last = &needle[needle_len - 1];
1377 
1378  /* Start at startpos plus the length of the needle */
1379  hptr = start_ptr + needle_len - 1;
1380  while (hptr < haystack_end)
1381  {
1382  /* Match the needle scanning *backward* */
1383  const char *nptr;
1384  const char *p;
1385 
1386  nptr = needle_last;
1387  p = hptr;
1388  while (*nptr == *p)
1389  {
1390  /* Matched it all? If so, return 1-based position */
1391  if (nptr == needle)
1392  return (char *) p;
1393  nptr--, p--;
1394  }
1395 
1396  /*
1397  * No match, so use the haystack char at hptr to decide how far to
1398  * advance. If the needle had any occurrence of that character
1399  * (or more precisely, one sharing the same skiptable entry)
1400  * before its last character, then we advance far enough to align
1401  * the last such needle character with that haystack position.
1402  * Otherwise we can advance by the whole needle length.
1403  */
1404  hptr += state->skiptable[(unsigned char) *hptr & skiptablemask];
1405  }
1406  }
1407 
1408  return 0; /* not found */
1409 }
int skiptable[256]
Definition: varlena.c:61
#define Assert(condition)
Definition: c.h:733

◆ text_position_setup()