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, Oid collid)
 
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:974
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
int errmsg(const char *fmt,...)
Definition: elog.c:784

Definition at line 5434 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 2933 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 5012 of file varlena.c.

Referenced by to_hex32(), and to_hex64().

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

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

Referenced by bytea_substring().

◆ REGEXP_REPLACE_BACKREF_CNT

#define REGEXP_REPLACE_BACKREF_CNT   10

Definition at line 4410 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 5432 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

Definition at line 43 of file varlena.c.

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

4319 {
4320  const char *p = VARDATA_ANY(replace_text);
4321  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4322  int eml = pg_database_encoding_max_length();
4323 
4324  for (;;)
4325  {
4326  const char *chunk_start = p;
4327  int so;
4328  int eo;
4329 
4330  /* Find next escape char. */
4331  if (eml == 1)
4332  {
4333  for (; p < p_end && *p != '\\'; p++)
4334  /* nothing */ ;
4335  }
4336  else
4337  {
4338  for (; p < p_end && *p != '\\'; p += pg_mblen(p))
4339  /* nothing */ ;
4340  }
4341 
4342  /* Copy the text we just scanned over, if any. */
4343  if (p > chunk_start)
4344  appendBinaryStringInfo(str, chunk_start, p - chunk_start);
4345 
4346  /* Done if at end of string, else advance over escape char. */
4347  if (p >= p_end)
4348  break;
4349  p++;
4350 
4351  if (p >= p_end)
4352  {
4353  /* Escape at very end of input. Treat same as unexpected char */
4354  appendStringInfoChar(str, '\\');
4355  break;
4356  }
4357 
4358  if (*p >= '1' && *p <= '9')
4359  {
4360  /* Use the back reference of regexp. */
4361  int idx = *p - '0';
4362 
4363  so = pmatch[idx].rm_so;
4364  eo = pmatch[idx].rm_eo;
4365  p++;
4366  }
4367  else if (*p == '&')
4368  {
4369  /* Use the entire matched string. */
4370  so = pmatch[0].rm_so;
4371  eo = pmatch[0].rm_eo;
4372  p++;
4373  }
4374  else if (*p == '\\')
4375  {
4376  /* \\ means transfer one \ to output. */
4377  appendStringInfoChar(str, '\\');
4378  p++;
4379  continue;
4380  }
4381  else
4382  {
4383  /*
4384  * If escape char is not followed by any expected char, just treat
4385  * it as ordinary data to copy. (XXX would it be better to throw
4386  * an error?)
4387  */
4388  appendStringInfoChar(str, '\\');
4389  continue;
4390  }
4391 
4392  if (so != -1 && eo != -1)
4393  {
4394  /*
4395  * Copy the text that is back reference of regexp. Note so and eo
4396  * are counted in characters not bytes.
4397  */
4398  char *chunk_start;
4399  int chunk_len;
4400 
4401  Assert(so >= data_pos);
4402  chunk_start = start_ptr;
4403  chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
4404  chunk_len = charlen_to_bytelen(chunk_start, eo - so);
4405  appendBinaryStringInfo(str, chunk_start, chunk_len);
4406  }
4407  }
4408 }
#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:264
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:175
#define Assert(condition)
Definition: c.h:732
int pg_mblen(const char *mbstr)
Definition: mbutils.c:752
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ appendStringInfoText()

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

Definition at line 4194 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().

4195 {
4197 }
#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:214

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

Definition at line 4853 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().

4854 {
4856  char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4857 
4858  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4859 }
#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:4895
#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 4895 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().

4897 {
4898  text *result;
4899  int nitems,
4900  *dims,
4901  ndims;
4902  Oid element_type;
4903  int typlen;
4904  bool typbyval;
4905  char typalign;
4907  bool printed = false;
4908  char *p;
4909  bits8 *bitmap;
4910  int bitmask;
4911  int i;
4912  ArrayMetaState *my_extra;
4913 
4914  ndims = ARR_NDIM(v);
4915  dims = ARR_DIMS(v);
4916  nitems = ArrayGetNItems(ndims, dims);
4917 
4918  /* if there are no elements, return an empty string */
4919  if (nitems == 0)
4920  return cstring_to_text_with_len("", 0);
4921 
4922  element_type = ARR_ELEMTYPE(v);
4923  initStringInfo(&buf);
4924 
4925  /*
4926  * We arrange to look up info about element type, including its output
4927  * conversion proc, only once per series of calls, assuming the element
4928  * type doesn't change underneath us.
4929  */
4930  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4931  if (my_extra == NULL)
4932  {
4933  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4934  sizeof(ArrayMetaState));
4935  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4936  my_extra->element_type = ~element_type;
4937  }
4938 
4939  if (my_extra->element_type != element_type)
4940  {
4941  /*
4942  * Get info about element type, including its output conversion proc
4943  */
4944  get_type_io_data(element_type, IOFunc_output,
4945  &my_extra->typlen, &my_extra->typbyval,
4946  &my_extra->typalign, &my_extra->typdelim,
4947  &my_extra->typioparam, &my_extra->typiofunc);
4948  fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
4949  fcinfo->flinfo->fn_mcxt);
4950  my_extra->element_type = element_type;
4951  }
4952  typlen = my_extra->typlen;
4953  typbyval = my_extra->typbyval;
4954  typalign = my_extra->typalign;
4955 
4956  p = ARR_DATA_PTR(v);
4957  bitmap = ARR_NULLBITMAP(v);
4958  bitmask = 1;
4959 
4960  for (i = 0; i < nitems; i++)
4961  {
4962  Datum itemvalue;
4963  char *value;
4964 
4965  /* Get source element, checking for NULL */
4966  if (bitmap && (*bitmap & bitmask) == 0)
4967  {
4968  /* if null_string is NULL, we just ignore null elements */
4969  if (null_string != NULL)
4970  {
4971  if (printed)
4972  appendStringInfo(&buf, "%s%s", fldsep, null_string);
4973  else
4974  appendStringInfoString(&buf, null_string);
4975  printed = true;
4976  }
4977  }
4978  else
4979  {
4980  itemvalue = fetch_att(p, typbyval, typlen);
4981 
4982  value = OutputFunctionCall(&my_extra->proc, itemvalue);
4983 
4984  if (printed)
4985  appendStringInfo(&buf, "%s%s", fldsep, value);
4986  else
4987  appendStringInfoString(&buf, value);
4988  printed = true;
4989 
4990  p = att_addlength_pointer(p, typlen, p);
4991  p = (char *) att_align_nominal(p, typalign);
4992  }
4993 
4994  /* advance bitmap pointer if any */
4995  if (bitmap)
4996  {
4997  bitmask <<= 1;
4998  if (bitmask == 0x100)
4999  {
5000  bitmap++;
5001  bitmask = 1;
5002  }
5003  }
5004  }
5005 
5006  result = cstring_to_text_with_len(buf.data, buf.len);
5007  pfree(buf.data);
5008 
5009  return result;
5010 }
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 @144 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:1031
char typalign
Definition: pg_type.h:170
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ARR_DIMS(a)
Definition: array.h:282
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
#define ARR_DATA_PTR(a)
Definition: array.h:310
int16 typlen
Definition: array.h:227
static char * buf
Definition: pg_test_fsync.c:68
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:46
uint8 bits8
Definition: c.h:365
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:771
int i
Oid element_type
Definition: array.h:226
Definition: c.h:549
#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 4869 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().

4870 {
4871  ArrayType *v;
4872  char *fldsep;
4873  char *null_string;
4874 
4875  /* returns NULL when first or second parameter is NULL */
4876  if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4877  PG_RETURN_NULL();
4878 
4879  v = PG_GETARG_ARRAYTYPE_P(0);
4880  fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4881 
4882  /* NULL null string is passed through as a null pointer */
4883  if (!PG_ARGISNULL(2))
4884  null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
4885  else
4886  null_string = NULL;
4887 
4888  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
4889 }
#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:4895
#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 2152 of file varlena.c.

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

Referenced by varstr_sortsupport().

2153 {
2154  BpChar *arg1 = DatumGetBpCharPP(x);
2155  BpChar *arg2 = DatumGetBpCharPP(y);
2156  char *a1p,
2157  *a2p;
2158  int len1,
2159  len2,
2160  result;
2161 
2162  a1p = VARDATA_ANY(arg1);
2163  a2p = VARDATA_ANY(arg2);
2164 
2165  len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2166  len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2167 
2168  result = memcmp(a1p, a2p, Min(len1, len2));
2169  if ((result == 0) && (len1 != len2))
2170  result = (len1 < len2) ? -1 : 1;
2171 
2172  /* We can't afford to leak memory here. */
2173  if (PointerGetDatum(arg1) != x)
2174  pfree(arg1);
2175  if (PointerGetDatum(arg2) != y)
2176  pfree(arg2);
2177 
2178  return result;
2179 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PointerGetDatum(X)
Definition: postgres.h:556
#define Min(x, y)
Definition: c.h:904
void pfree(void *pointer)
Definition: mcxt.c:1031
int bpchartruelen(char *s, int len)
Definition: varchar.c:672
#define DatumGetBpCharPP(X)
Definition: fmgr.h:287
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:549

◆ btnametextcmp()

Datum btnametextcmp ( PG_FUNCTION_ARGS  )

Definition at line 2902 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().

2903 {
2904  Name arg1 = PG_GETARG_NAME(0);
2905  text *arg2 = PG_GETARG_TEXT_PP(1);
2906  int32 result;
2907 
2908  result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
2909  VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
2910  PG_GET_COLLATION());
2911 
2912  PG_FREE_IF_COPY(arg2, 1);
2913 
2914  PG_RETURN_INT32(result);
2915 }
#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:346
#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:1468
Definition: c.h:603
#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:609
Definition: c.h:549
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 3107 of file varlena.c.

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

3108 {
3109  text *arg1 = PG_GETARG_TEXT_PP(0);
3110  text *arg2 = PG_GETARG_TEXT_PP(1);
3111  int result;
3112 
3113  result = internal_text_pattern_compare(arg1, arg2, PG_GET_COLLATION());
3114 
3115  PG_FREE_IF_COPY(arg1, 0);
3116  PG_FREE_IF_COPY(arg2, 1);
3117 
3118  PG_RETURN_INT32(result);
3119 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549
static int internal_text_pattern_compare(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:2999

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 3123 of file varlena.c.

References check_collation_set(), ereport, errcode(), errmsg(), ERROR, get_collation_isdeterministic(), MemoryContextSwitchTo(), PG_GETARG_POINTER, PG_RETURN_VOID, SortSupportData::ssup_collation, SortSupportData::ssup_cxt, and varstr_sortsupport().

3124 {
3126  Oid collid = ssup->ssup_collation;
3127  MemoryContext oldcontext;
3128 
3129  check_collation_set(collid);
3130 
3131  if (!get_collation_isdeterministic(collid))
3132  ereport(ERROR,
3133  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3134  errmsg("nondeterministic collations are not supported for operator class \"%s\"",
3135  "text_pattern_ops")));
3136 
3137  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
3138 
3139  /* Use generic string SortSupport, forcing "C" collation */
3140  varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID);
3141 
3142  MemoryContextSwitchTo(oldcontext);
3143 
3144  PG_RETURN_VOID();
3145 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:942
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
MemoryContext ssup_cxt
Definition: sortsupport.h:66
static void check_collation_set(Oid collid)
Definition: varlena.c:1445
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1953
#define ereport(elevel, rest)
Definition: elog.h:141
#define PG_RETURN_VOID()
Definition: fmgr.h:339
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

Definition at line 1911 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().

1912 {
1913  text *arg1 = PG_GETARG_TEXT_PP(0);
1914  text *arg2 = PG_GETARG_TEXT_PP(1);
1915  int32 result;
1916 
1917  result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1918 
1919  PG_FREE_IF_COPY(arg1, 0);
1920  PG_FREE_IF_COPY(arg2, 1);
1921 
1922  PG_RETURN_INT32(result);
1923 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define PG_GET_COLLATION()
Definition: fmgr.h:193
signed int int32
Definition: c.h:346
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1684
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ bttextnamecmp()

Datum bttextnamecmp ( PG_FUNCTION_ARGS  )

Definition at line 2918 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().

2919 {
2920  text *arg1 = PG_GETARG_TEXT_PP(0);
2921  Name arg2 = PG_GETARG_NAME(1);
2922  int32 result;
2923 
2924  result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
2925  NameStr(*arg2), strlen(NameStr(*arg2)),
2926  PG_GET_COLLATION());
2927 
2928  PG_FREE_IF_COPY(arg1, 0);
2929 
2930  PG_RETURN_INT32(result);
2931 }
#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:346
#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:1468
Definition: c.h:603
#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:609
Definition: c.h:549
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1926 of file varlena.c.

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

1927 {
1929  Oid collid = ssup->ssup_collation;
1930  MemoryContext oldcontext;
1931 
1932  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1933 
1934  /* Use generic string SortSupport */
1935  varstr_sortsupport(ssup, TEXTOID, collid);
1936 
1937  MemoryContextSwitchTo(oldcontext);
1938 
1939  PG_RETURN_VOID();
1940 }
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:1953
#define PG_RETURN_VOID()
Definition: fmgr.h:339

◆ build_concat_foutcache()

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

Definition at line 5193 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().

5194 {
5195  FmgrInfo *foutcache;
5196  int i;
5197 
5198  /* We keep the info in fn_mcxt so it survives across calls */
5199  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5200  PG_NARGS() * sizeof(FmgrInfo));
5201 
5202  for (i = argidx; i < PG_NARGS(); i++)
5203  {
5204  Oid valtype;
5205  Oid typOutput;
5206  bool typIsVarlena;
5207 
5208  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5209  if (!OidIsValid(valtype))
5210  elog(ERROR, "could not determine data type of concat() input");
5211 
5212  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5213  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5214  }
5215 
5216  fcinfo->flinfo->fn_extra = foutcache;
5217 
5218  return foutcache;
5219 }
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:638
#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:771
#define elog(elevel,...)
Definition: elog.h:226
int i

◆ bytea_catenate()

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

Definition at line 3186 of file varlena.c.

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

Referenced by bytea_overlay(), and byteacat().

3187 {
3188  bytea *result;
3189  int len1,
3190  len2,
3191  len;
3192  char *ptr;
3193 
3194  len1 = VARSIZE_ANY_EXHDR(t1);
3195  len2 = VARSIZE_ANY_EXHDR(t2);
3196 
3197  /* paranoia ... probably should throw error instead? */
3198  if (len1 < 0)
3199  len1 = 0;
3200  if (len2 < 0)
3201  len2 = 0;
3202 
3203  len = len1 + len2 + VARHDRSZ;
3204  result = (bytea *) palloc(len);
3205 
3206  /* Set size of result string... */
3207  SET_VARSIZE(result, len);
3208 
3209  /* Fill data field of result string... */
3210  ptr = VARDATA(result);
3211  if (len1 > 0)
3212  memcpy(ptr, VARDATA_ANY(t1), len1);
3213  if (len2 > 0)
3214  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
3215 
3216  return result;
3217 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:555
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:924
Definition: c.h:549
#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 3343 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().

3344 {
3345  bytea *result;
3346  bytea *s1;
3347  bytea *s2;
3348  int sp_pl_sl;
3349 
3350  /*
3351  * Check for possible integer-overflow cases. For negative sp, throw a
3352  * "substring length" error because that's what should be expected
3353  * according to the spec's definition of OVERLAY().
3354  */
3355  if (sp <= 0)
3356  ereport(ERROR,
3357  (errcode(ERRCODE_SUBSTRING_ERROR),
3358  errmsg("negative substring length not allowed")));
3359  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
3360  ereport(ERROR,
3361  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3362  errmsg("integer out of range")));
3363 
3364  s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
3365  s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
3366  result = bytea_catenate(s1, t2);
3367  result = bytea_catenate(result, s2);
3368 
3369  return result;
3370 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3186
int errcode(int sqlerrcode)
Definition: elog.c:570
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3261
#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:784
Definition: c.h:549

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 4172 of file varlena.c.

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

4173 {
4175  MemoryContext oldcontext;
4176 
4177  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
4178 
4179  /* Use generic string SortSupport, forcing "C" collation */
4180  varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
4181 
4182  MemoryContextSwitchTo(oldcontext);
4183 
4184  PG_RETURN_VOID();
4185 }
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:1953
#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:555
StringInfoData * StringInfo
Definition: stringinfo.h:43
#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:732
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3572
void * palloc(Size size)
Definition: mcxt.c:924
Definition: c.h:549
#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:43
static struct @144 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:5121
Definition: c.h:549
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 3238 of file varlena.c.

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

3239 {
3241  PG_GETARG_INT32(1),
3242  PG_GETARG_INT32(2),
3243  false));
3244 }
#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:3261

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3252 of file varlena.c.

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

3253 {
3255  PG_GETARG_INT32(1),
3256  -1,
3257  true));
3258 }
#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:3261

◆ bytea_substring()

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

Definition at line 3261 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().

3265 {
3266  int S1; /* adjusted start position */
3267  int L1; /* adjusted substring length */
3268 
3269  S1 = Max(S, 1);
3270 
3271  if (length_not_specified)
3272  {
3273  /*
3274  * Not passed a length - DatumGetByteaPSlice() grabs everything to the
3275  * end of the string if we pass it a negative value for length.
3276  */
3277  L1 = -1;
3278  }
3279  else
3280  {
3281  /* end position */
3282  int E = S + L;
3283 
3284  /*
3285  * A negative value for L is the only way for the end position to be
3286  * before the start. SQL99 says to throw an error.
3287  */
3288  if (E < S)
3289  ereport(ERROR,
3290  (errcode(ERRCODE_SUBSTRING_ERROR),
3291  errmsg("negative substring length not allowed")));
3292 
3293  /*
3294  * A zero or negative value for the end position can happen if the
3295  * start was negative or one. SQL99 says to return a zero-length
3296  * string.
3297  */
3298  if (E < 1)
3299  return PG_STR_GET_BYTEA("");
3300 
3301  L1 = E - S1;
3302  }
3303 
3304  /*
3305  * If the start position is past the end of the string, SQL99 says to
3306  * return a zero-length string -- DatumGetByteaPSlice() will do that for
3307  * us. Convert to zero-based starting position
3308  */
3309  return DatumGetByteaPSlice(str, S1 - 1, L1);
3310 }
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:297
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:3219
#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:898
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 3171 of file varlena.c.

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

3172 {
3173  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3174  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3175 
3177 }
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3186
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
Definition: c.h:549

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

Definition at line 4150 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().

4151 {
4152  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4153  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4154  int len1,
4155  len2;
4156  int cmp;
4157 
4158  len1 = VARSIZE_ANY_EXHDR(arg1);
4159  len2 = VARSIZE_ANY_EXHDR(arg2);
4160 
4161  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4162  if ((cmp == 0) && (len1 != len2))
4163  cmp = (len1 < len2) ? -1 : 1;
4164 
4165  PG_FREE_IF_COPY(arg1, 0);
4166  PG_FREE_IF_COPY(arg2, 1);
4167 
4168  PG_RETURN_INT32(cmp);
4169 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:904
#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:549
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 4006 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().

4007 {
4008  Datum arg1 = PG_GETARG_DATUM(0);
4009  Datum arg2 = PG_GETARG_DATUM(1);
4010  bool result;
4011  Size len1,
4012  len2;
4013 
4014  /*
4015  * We can use a fast path for unequal lengths, which might save us from
4016  * having to detoast one or both values.
4017  */
4018  len1 = toast_raw_datum_size(arg1);
4019  len2 = toast_raw_datum_size(arg2);
4020  if (len1 != len2)
4021  result = false;
4022  else
4023  {
4024  bytea *barg1 = DatumGetByteaPP(arg1);
4025  bytea *barg2 = DatumGetByteaPP(arg2);
4026 
4027  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4028  len1 - VARHDRSZ) == 0);
4029 
4030  PG_FREE_IF_COPY(barg1, 0);
4031  PG_FREE_IF_COPY(barg2, 1);
4032  }
4033 
4034  PG_RETURN_BOOL(result);
4035 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define VARHDRSZ
Definition: c.h:555
#define DatumGetByteaPP(X)
Definition: fmgr.h:285
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:768
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
size_t Size
Definition: c.h:466
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

Definition at line 4130 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().

4131 {
4132  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4133  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4134  int len1,
4135  len2;
4136  int cmp;
4137 
4138  len1 = VARSIZE_ANY_EXHDR(arg1);
4139  len2 = VARSIZE_ANY_EXHDR(arg2);
4140 
4141  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4142 
4143  PG_FREE_IF_COPY(arg1, 0);
4144  PG_FREE_IF_COPY(arg2, 1);
4145 
4146  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
4147 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:904
#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:549
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 3452 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.

3453 {
3454  bytea *v = PG_GETARG_BYTEA_PP(0);
3455  int32 n = PG_GETARG_INT32(1);
3456  int byteNo,
3457  bitNo;
3458  int len;
3459  int byte;
3460 
3461  len = VARSIZE_ANY_EXHDR(v);
3462 
3463  if (n < 0 || n >= len * 8)
3464  ereport(ERROR,
3465  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3466  errmsg("index %d out of valid range, 0..%d",
3467  n, len * 8 - 1)));
3468 
3469  byteNo = n / 8;
3470  bitNo = n % 8;
3471 
3472  byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3473 
3474  if (byte & (1 << bitNo))
3475  PG_RETURN_INT32(1);
3476  else
3477  PG_RETURN_INT32(0);
3478 }
#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:570
signed int int32
Definition: c.h:346
#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:784
Definition: c.h:549

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

Definition at line 3423 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.

3424 {
3425  bytea *v = PG_GETARG_BYTEA_PP(0);
3426  int32 n = PG_GETARG_INT32(1);
3427  int len;
3428  int byte;
3429 
3430  len = VARSIZE_ANY_EXHDR(v);
3431 
3432  if (n < 0 || n >= len)
3433  ereport(ERROR,
3434  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3435  errmsg("index %d out of valid range, 0..%d",
3436  n, len - 1)));
3437 
3438  byte = ((unsigned char *) VARDATA_ANY(v))[n];
3439 
3440  PG_RETURN_INT32(byte);
3441 }
#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:570
signed int int32
Definition: c.h:346
#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:784
Definition: c.h:549

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

Definition at line 4110 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().

4111 {
4112  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4113  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4114  int len1,
4115  len2;
4116  int cmp;
4117 
4118  len1 = VARSIZE_ANY_EXHDR(arg1);
4119  len2 = VARSIZE_ANY_EXHDR(arg2);
4120 
4121  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4122 
4123  PG_FREE_IF_COPY(arg1, 0);
4124  PG_FREE_IF_COPY(arg2, 1);
4125 
4126  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
4127 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:904
#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:549
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:555
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
#define VAL(CH)
Definition: varlena.c:262
Definition: c.h:549
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

Definition at line 4090 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().

4091 {
4092  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4093  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4094  int len1,
4095  len2;
4096  int cmp;
4097 
4098  len1 = VARSIZE_ANY_EXHDR(arg1);
4099  len2 = VARSIZE_ANY_EXHDR(arg2);
4100 
4101  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4102 
4103  PG_FREE_IF_COPY(arg1, 0);
4104  PG_FREE_IF_COPY(arg2, 1);
4105 
4106  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
4107 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:904
#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:549
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 4070 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().

4071 {
4072  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4073  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4074  int len1,
4075  len2;
4076  int cmp;
4077 
4078  len1 = VARSIZE_ANY_EXHDR(arg1);
4079  len2 = VARSIZE_ANY_EXHDR(arg2);
4080 
4081  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4082 
4083  PG_FREE_IF_COPY(arg1, 0);
4084  PG_FREE_IF_COPY(arg2, 1);
4085 
4086  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
4087 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:904
#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:549
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 4038 of file varlena.c.

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

4039 {
4040  Datum arg1 = PG_GETARG_DATUM(0);
4041  Datum arg2 = PG_GETARG_DATUM(1);
4042  bool result;
4043  Size len1,
4044  len2;
4045 
4046  /*
4047  * We can use a fast path for unequal lengths, which might save us from
4048  * having to detoast one or both values.
4049  */
4050  len1 = toast_raw_datum_size(arg1);
4051  len2 = toast_raw_datum_size(arg2);
4052  if (len1 != len2)
4053  result = true;
4054  else
4055  {
4056  bytea *barg1 = DatumGetByteaPP(arg1);
4057  bytea *barg2 = DatumGetByteaPP(arg2);
4058 
4059  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4060  len1 - VARHDRSZ) != 0);
4061 
4062  PG_FREE_IF_COPY(barg1, 0);
4063  PG_FREE_IF_COPY(barg2, 1);
4064  }
4065 
4066  PG_RETURN_BOOL(result);
4067 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define VARHDRSZ
Definition: c.h:555
#define DatumGetByteaPP(X)
Definition: fmgr.h:285
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:768
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
size_t Size
Definition: c.h:466
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 3155 of file varlena.c.

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

3156 {
3157  Datum str = PG_GETARG_DATUM(0);
3158 
3159  /* We need not detoast the input at all */
3161 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define VARHDRSZ
Definition: c.h:555
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:768
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:924
#define elog(elevel,...)
Definition: elog.h:226
int i
Definition: c.h:549
long val
Definition: informix.c:684
#define DIG(VAL)
Definition: varlena.c:263

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 3320 of file varlena.c.

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

3321 {
3322  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3323  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3324  int sp = PG_GETARG_INT32(2); /* substring start position */
3325  int sl = PG_GETARG_INT32(3); /* substring length */
3326 
3327  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3328 }
#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:3343
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
Definition: c.h:549

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3331 of file varlena.c.

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

3332 {
3333  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3334  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3335  int sp = PG_GETARG_INT32(2); /* substring start position */
3336  int sl;
3337 
3338  sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
3339  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3340 }
#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:3343
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:302
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:549

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 3379 of file varlena.c.

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

3380 {
3381  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3382  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3383  int pos;
3384  int px,
3385  p;
3386  int len1,
3387  len2;
3388  char *p1,
3389  *p2;
3390 
3391  len1 = VARSIZE_ANY_EXHDR(t1);
3392  len2 = VARSIZE_ANY_EXHDR(t2);
3393 
3394  if (len2 <= 0)
3395  PG_RETURN_INT32(1); /* result for empty pattern */
3396 
3397  p1 = VARDATA_ANY(t1);
3398  p2 = VARDATA_ANY(t2);
3399 
3400  pos = 0;
3401  px = (len1 - len2);
3402  for (p = 0; p <= px; p++)
3403  {
3404  if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
3405  {
3406  pos = p + 1;
3407  break;
3408  };
3409  p1++;
3410  };
3411 
3412  PG_RETURN_INT32(pos);
3413 }
#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:549

◆ 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:555
StringInfoData * StringInfo
Definition: stringinfo.h:43
#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:68
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:530
void * palloc(Size size)
Definition: mcxt.c:924
Definition: c.h:549
#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:549

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 3521 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.

3522 {
3523  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3524  int32 n = PG_GETARG_INT32(1);
3525  int32 newBit = PG_GETARG_INT32(2);
3526  int len;
3527  int oldByte,
3528  newByte;
3529  int byteNo,
3530  bitNo;
3531 
3532  len = VARSIZE(res) - VARHDRSZ;
3533 
3534  if (n < 0 || n >= len * 8)
3535  ereport(ERROR,
3536  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3537  errmsg("index %d out of valid range, 0..%d",
3538  n, len * 8 - 1)));
3539 
3540  byteNo = n / 8;
3541  bitNo = n % 8;
3542 
3543  /*
3544  * sanity check!
3545  */
3546  if (newBit != 0 && newBit != 1)
3547  ereport(ERROR,
3548  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3549  errmsg("new bit must be 0 or 1")));
3550 
3551  /*
3552  * Update the byte.
3553  */
3554  oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3555 
3556  if (newBit == 0)
3557  newByte = oldByte & (~(1 << bitNo));
3558  else
3559  newByte = oldByte | (1 << bitNo);
3560 
3561  ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3562 
3563  PG_RETURN_BYTEA_P(res);
3564 }
#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:555
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:308
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
signed int int32
Definition: c.h:346
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: c.h:549

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

Definition at line 3489 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.

3490 {
3491  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3492  int32 n = PG_GETARG_INT32(1);
3493  int32 newByte = PG_GETARG_INT32(2);
3494  int len;
3495 
3496  len = VARSIZE(res) - VARHDRSZ;
3497 
3498  if (n < 0 || n >= len)
3499  ereport(ERROR,
3500  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3501  errmsg("index %d out of valid range, 0..%d",
3502  n, len - 1)));
3503 
3504  /*
3505  * Now set the byte.
3506  */
3507  ((unsigned char *) VARDATA(res))[n] = newByte;
3508 
3509  PG_RETURN_BYTEA_P(res);
3510 }
#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:555
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:308
int errcode(int sqlerrcode)
Definition: elog.c:570
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
signed int int32
Definition: c.h:346
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: c.h:549

◆ 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:752

◆ check_collation_set()

static void check_collation_set ( Oid  collid)
static

Definition at line 1445 of file varlena.c.

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

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

1446 {
1447  if (!OidIsValid(collid))
1448  {
1449  /*
1450  * This typically means that the parser could not resolve a conflict
1451  * of implicit collations, so report it that way.
1452  */
1453  ereport(ERROR,
1454  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1455  errmsg("could not determine which collation to use for string comparison"),
1456  errhint("Use the COLLATE clause to set the collation explicitly.")));
1457  }
1458 }
int errhint(const char *fmt,...)
Definition: elog.c:974
int errcode(int sqlerrcode)
Definition: elog.c:570
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ check_replace_text_has_escape_char()

static bool check_replace_text_has_escape_char ( const text replace_text)
static

Definition at line 4283 of file varlena.c.

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

Referenced by replace_text_regexp().

4284 {
4285  const char *p = VARDATA_ANY(replace_text);
4286  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4287 
4289  {
4290  for (; p < p_end; p++)
4291  {
4292  if (*p == '\\')
4293  return true;
4294  }
4295  }
4296  else
4297  {
4298  for (; p < p_end; p += pg_mblen(p))
4299  {
4300  if (*p == '\\')
4301  return true;
4302  }
4303  }
4304 
4305  return false;
4306 }
#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:752
#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 5231 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().

5233 {
5234  text *result;
5236  FmgrInfo *foutcache;
5237  bool first_arg = true;
5238  int i;
5239 
5240  /*
5241  * concat(VARIADIC some-array) is essentially equivalent to
5242  * array_to_text(), ie concat the array elements with the given separator.
5243  * So we just pass the case off to that code.
5244  */
5245  if (get_fn_expr_variadic(fcinfo->flinfo))
5246  {
5247  ArrayType *arr;
5248 
5249  /* Should have just the one argument */
5250  Assert(argidx == PG_NARGS() - 1);
5251 
5252  /* concat(VARIADIC NULL) is defined as NULL */
5253  if (PG_ARGISNULL(argidx))
5254  return NULL;
5255 
5256  /*
5257  * Non-null argument had better be an array. We assume that any call
5258  * context that could let get_fn_expr_variadic return true will have
5259  * checked that a VARIADIC-labeled parameter actually is an array. So
5260  * it should be okay to just Assert that it's an array rather than
5261  * doing a full-fledged error check.
5262  */
5264 
5265  /* OK, safe to fetch the array value */
5266  arr = PG_GETARG_ARRAYTYPE_P(argidx);
5267 
5268  /*
5269  * And serialize the array. We tell array_to_text to ignore null
5270  * elements, which matches the behavior of the loop below.
5271  */
5272  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5273  }
5274 
5275  /* Normal case without explicit VARIADIC marker */
5276  initStringInfo(&str);
5277 
5278  /* Get output function info, building it if first time through */
5279  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5280  if (foutcache == NULL)
5281  foutcache = build_concat_foutcache(fcinfo, argidx);
5282 
5283  for (i = argidx; i < PG_NARGS(); i++)
5284  {
5285  if (!PG_ARGISNULL(i))
5286  {
5288 
5289  /* add separator if appropriate */
5290  if (first_arg)
5291  first_arg = false;
5292  else
5293  appendStringInfoString(&str, sepstr);
5294 
5295  /* call the appropriate type output function, append the result */
5297  OutputFunctionCall(&foutcache[i], value));
5298  }
5299  }
5300 
5301  result = cstring_to_text_with_len(str.data, str.len);
5302  pfree(str.data);
5303 
5304  return result;
5305 }
Definition: fmgr.h:56
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
static struct @144 value
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1951
#define OidIsValid(objectId)
Definition: c.h:638
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:1031
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:4895
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
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:732
#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:5193
Definition: c.h:549

◆ 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(), 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_array_element_text(), jsonb_object_field_text(), jsonb_typeof(), 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(), elements_worker_jsonb(), ExecEvalXmlExpr(), executeLikeRegex(), fsm_page_contents(), get_array_element_end(), get_array_end(), get_jsonb_path_all(), 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_array_element_text(), jsonb_object_field_text(), jsonb_pretty(), 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:555
void * palloc(Size size)
Definition: mcxt.c:924
Definition: c.h:549
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ internal_text_pattern_compare()

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

Definition at line 2999 of file varlena.c.

References check_collation_set(), ereport, errcode(), errmsg(), ERROR, get_collation_isdeterministic(), 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().

3000 {
3001  int result;
3002  int len1,
3003  len2;
3004 
3005  check_collation_set(collid);
3006 
3007  /*
3008  * XXX We cannot use a text_pattern_ops index for nondeterministic
3009  * collations, because these operators intentionally ignore the collation.
3010  * However, the planner has no way to know that, so it might choose such
3011  * an index for an "=" clause, which would lead to wrong results. This
3012  * check here doesn't prevent choosing the index, but it will at least
3013  * error out if the index is chosen. A text_pattern_ops index on a column
3014  * with nondeterministic collation is pretty useless anyway, since LIKE
3015  * etc. won't work there either. A future possibility would be to
3016  * annotate the operator class or its members in the catalog to avoid the
3017  * index. Another alternative is to stay away from the *_pattern_ops
3018  * operator classes and prefer creating LIKE-supporting indexes with
3019  * COLLATE "C".
3020  */
3021  if (!get_collation_isdeterministic(collid))
3022  ereport(ERROR,
3023  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3024  errmsg("nondeterministic collations are not supported for operator class \"%s\"",
3025  "text_pattern_ops")));
3026 
3027  len1 = VARSIZE_ANY_EXHDR(arg1);
3028  len2 = VARSIZE_ANY_EXHDR(arg2);
3029 
3030  result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3031  if (result != 0)
3032  return result;
3033  else if (len1 < len2)
3034  return -1;
3035  else if (len1 > len2)
3036  return 1;
3037  else
3038  return 0;
3039 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:904
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:942
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
static void check_collation_set(Oid collid)
Definition: varlena.c:1445
#define ereport(elevel, rest)
Definition: elog.h:141
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5121 of file varlena.c.

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

Referenced by bytea_string_agg_transfn(), and string_agg_transfn().

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

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3594 of file varlena.c.

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

Referenced by nameiclike(), and nameicnlike().

3595 {
3596  Name s = PG_GETARG_NAME(0);
3597 
3599 }
Definition: c.h:603
#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:609
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ nameeqtext()

Datum nameeqtext ( PG_FUNCTION_ARGS  )

Definition at line 2802 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().

2803 {
2804  Name arg1 = PG_GETARG_NAME(0);
2805  text *arg2 = PG_GETARG_TEXT_PP(1);
2806  size_t len1 = strlen(NameStr(*arg1));
2807  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2808  Oid collid = PG_GET_COLLATION();
2809  bool result;
2810 
2811  check_collation_set(collid);
2812 
2813  if (collid == C_COLLATION_OID)
2814  result = (len1 == len2 &&
2815  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2816  else
2817  result = (varstr_cmp(NameStr(*arg1), len1,
2818  VARDATA_ANY(arg2), len2,
2819  collid) == 0);
2820 
2821  PG_FREE_IF_COPY(arg2, 1);
2822 
2823  PG_RETURN_BOOL(result);
2824 }
#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:1468
static void check_collation_set(Oid collid)
Definition: varlena.c:1445
Definition: c.h:603
#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:609
Definition: c.h:549
#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 2185 of file varlena.c.

References DatumGetName, NAMEDATALEN, and NameStr.

Referenced by varstr_sortsupport().

2186 {
2187  Name arg1 = DatumGetName(x);
2188  Name arg2 = DatumGetName(y);
2189 
2190  return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2191 }
#define NAMEDATALEN
#define DatumGetName(X)
Definition: postgres.h:585
Definition: c.h:603
#define NameStr(name)
Definition: c.h:609

◆ namefastcmp_locale()

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

Definition at line 2228 of file varlena.c.

References DatumGetName, NameStr, and varstrfastcmp_locale().

Referenced by varstr_sortsupport().

2229 {
2230  Name arg1 = DatumGetName(x);
2231  Name arg2 = DatumGetName(y);
2232 
2233  return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)),
2234  NameStr(*arg2), strlen(NameStr(*arg2)),
2235  ssup);
2236 }
#define DatumGetName(X)
Definition: postgres.h:585
Definition: c.h:603
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2242
#define NameStr(name)
Definition: c.h:609

◆ namegetext()

Datum namegetext ( PG_FUNCTION_ARGS  )

Definition at line 2958 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2959 {
2961 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2933
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2902

◆ namegttext()

Datum namegttext ( PG_FUNCTION_ARGS  )

Definition at line 2952 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2953 {
2955 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2933
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2902

◆ nameletext()

Datum nameletext ( PG_FUNCTION_ARGS  )

Definition at line 2946 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2947 {
2949 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2933
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2902

◆ namelttext()

Datum namelttext ( PG_FUNCTION_ARGS  )

Definition at line 2940 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2941 {
2943 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2933
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2902

◆ namenetext()

Datum namenetext ( PG_FUNCTION_ARGS  )

Definition at line 2852 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().

2853 {
2854  Name arg1 = PG_GETARG_NAME(0);
2855  text *arg2 = PG_GETARG_TEXT_PP(1);
2856  size_t len1 = strlen(NameStr(*arg1));
2857  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2858  Oid collid = PG_GET_COLLATION();
2859  bool result;
2860 
2861  check_collation_set(collid);
2862 
2863  if (collid == C_COLLATION_OID)
2864  result = !(len1 == len2 &&
2865  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2866  else
2867  result = !(varstr_cmp(NameStr(*arg1), len1,
2868  VARDATA_ANY(arg2), len2,
2869  collid) == 0);
2870 
2871  PG_FREE_IF_COPY(arg2, 1);
2872 
2873  PG_RETURN_BOOL(result);
2874 }
#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:1468
static void check_collation_set(Oid collid)
Definition: varlena.c:1445
Definition: c.h:603
#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:609
Definition: c.h:549
#define PG_GETARG_NAME(n)
Definition: fmgr.h:273

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

Definition at line 5067 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.

5068 {
5070  int32 result;
5071  int typlen;
5072 
5073  /* On first call, get the input type's typlen, and save at *fn_extra */
5074  if (fcinfo->flinfo->fn_extra == NULL)
5075  {
5076  /* Lookup the datatype of the supplied argument */
5077  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5078 
5079  typlen = get_typlen(argtypeid);
5080  if (typlen == 0) /* should not happen */
5081  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5082 
5083  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5084  sizeof(int));
5085  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5086  }
5087  else
5088  typlen = *((int *) fcinfo->flinfo->fn_extra);
5089 
5090  if (typlen == -1)
5091  {
5092  /* varlena type, possibly toasted */
5093  result = toast_datum_size(value);
5094  }
5095  else if (typlen == -2)
5096  {
5097  /* cstring */
5098  result = strlen(DatumGetCString(value)) + 1;
5099  }
5100  else
5101  {
5102  /* ordinary fixed-width type */
5103  result = typlen;
5104  }
5105 
5106  PG_RETURN_INT32(result);
5107 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
static struct @144 value
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:346
Size toast_datum_size(Datum value)
Definition: detoast.c:824
#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:771
#define elog(elevel,...)
Definition: elog.h:226

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

Definition at line 4208 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().

4209 {
4210  text *src_text = PG_GETARG_TEXT_PP(0);
4211  text *from_sub_text = PG_GETARG_TEXT_PP(1);
4212  text *to_sub_text = PG_GETARG_TEXT_PP(2);
4213  int src_text_len;
4214  int from_sub_text_len;
4216  text *ret_text;
4217  int chunk_len;
4218  char *curr_ptr;
4219  char *start_ptr;
4221  bool found;
4222 
4223  src_text_len = VARSIZE_ANY_EXHDR(src_text);
4224  from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4225 
4226  /* Return unmodified source string if empty source or pattern */
4227  if (src_text_len < 1 || from_sub_text_len < 1)
4228  {
4229  PG_RETURN_TEXT_P(src_text);
4230  }
4231 
4232  text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4233 
4234  found = text_position_next(&state);
4235 
4236  /* When the from_sub_text is not found, there is nothing to do. */
4237  if (!found)
4238  {
4239  text_position_cleanup(&state);
4240  PG_RETURN_TEXT_P(src_text);
4241  }
4242  curr_ptr = text_position_get_match_ptr(&state);
4243  start_ptr = VARDATA_ANY(src_text);
4244 
4245  initStringInfo(&str);
4246 
4247  do
4248  {
4250 
4251  /* copy the data skipped over by last text_position_next() */
4252  chunk_len = curr_ptr - start_ptr;
4253  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4254 
4255  appendStringInfoText(&str, to_sub_text);
4256 
4257  start_ptr = curr_ptr + from_sub_text_len;
4258 
4259  found = text_position_next(&state);
4260  if (found)
4261  curr_ptr = text_position_get_match_ptr(&state);
4262  }
4263  while (found);
4264 
4265  /* copy trailing data */
4266  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4267  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4268 
4269  text_position_cleanup(&state);
4270 
4271  ret_text = cstring_to_text_with_len(str.data, str.len);
4272  pfree(str.data);
4273 
4274  PG_RETURN_TEXT_P(ret_text);
4275 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1277
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1410
#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:1031
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4194
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
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:1439
#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:1151
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:549
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214

◆ replace_text_regexp()

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

Definition at line 4421 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().

4423 {
4424  text *ret_text;
4425  regex_t *re = (regex_t *) regexp;
4426  int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4429  pg_wchar *data;
4430  size_t data_len;
4431  int search_start;
4432  int data_pos;
4433  char *start_ptr;
4434  bool have_escape;
4435 
4436  initStringInfo(&buf);
4437 
4438  /* Convert data string to wide characters. */
4439  data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4440  data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4441 
4442  /* Check whether replace_text has escape char. */
4443  have_escape = check_replace_text_has_escape_char(replace_text);
4444 
4445  /* start_ptr points to the data_pos'th character of src_text */
4446  start_ptr = (char *) VARDATA_ANY(src_text);
4447  data_pos = 0;
4448 
4449  search_start = 0;
4450  while (search_start <= data_len)
4451  {
4452  int regexec_result;
4453 
4455 
4456  regexec_result = pg_regexec(re,
4457  data,
4458  data_len,
4459  search_start,
4460  NULL, /* no details */
4462  pmatch,
4463  0);
4464 
4465  if (regexec_result == REG_NOMATCH)
4466  break;
4467 
4468  if (regexec_result != REG_OKAY)
4469  {
4470  char errMsg[100];
4471 
4473  pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4474  ereport(ERROR,
4475  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4476  errmsg("regular expression failed: %s", errMsg)));
4477  }
4478 
4479  /*
4480  * Copy the text to the left of the match position. Note we are given
4481  * character not byte indexes.
4482  */
4483  if (pmatch[0].rm_so - data_pos > 0)
4484  {
4485  int chunk_len;
4486 
4487  chunk_len = charlen_to_bytelen(start_ptr,
4488  pmatch[0].rm_so - data_pos);
4489  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4490 
4491  /*
4492  * Advance start_ptr over that text, to avoid multiple rescans of
4493  * it if the replace_text contains multiple back-references.
4494  */
4495  start_ptr += chunk_len;
4496  data_pos = pmatch[0].rm_so;
4497  }
4498 
4499  /*
4500  * Copy the replace_text. Process back references when the
4501  * replace_text has escape characters.
4502  */
4503  if (have_escape)
4504  appendStringInfoRegexpSubstr(&buf, replace_text, pmatch,
4505  start_ptr, data_pos);
4506  else
4507  appendStringInfoText(&buf, replace_text);
4508 
4509  /* Advance start_ptr and data_pos over the matched text. */
4510  start_ptr += charlen_to_bytelen(start_ptr,
4511  pmatch[0].rm_eo - data_pos);
4512  data_pos = pmatch[0].rm_eo;
4513 
4514  /*
4515  * When global option is off, replace the first instance only.
4516  */
4517  if (!glob)
4518  break;
4519 
4520  /*
4521  * Advance search position. Normally we start the next search at the
4522  * end of the previous match; but if the match was of zero length, we
4523  * have to advance by one character, or we'd just find the same match
4524  * again.
4525  */
4526  search_start = data_pos;
4527  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4528  search_start++;
4529  }
4530 
4531  /*
4532  * Copy the text to the right of the last match.
4533  */
4534  if (data_pos < data_len)
4535  {
4536  int chunk_len;
4537 
4538  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4539  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4540  }
4541 
4542  ret_text = cstring_to_text_with_len(buf.data, buf.len);
4543  pfree(buf.data);
4544  pfree(data);
4545 
4546  return ret_text;
4547 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
regoff_t rm_so
Definition: regex.h:85
int errcode(int sqlerrcode)
Definition: elog.c:570
regoff_t rm_eo
Definition: regex.h:86
void pfree(void *pointer)
Definition: mcxt.c:1031
#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:4283
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:4194
static char * buf
Definition: pg_test_fsync.c:68
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:46
#define REGEXP_REPLACE_BACKREF_CNT
Definition: varlena.c:4410
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:715
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4316
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:924
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define REG_NOMATCH
Definition: regex.h:138
Definition: c.h:549
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214
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 5961 of file varlena.c.

Referenced by varstr_levenshtein().

5962 {
5963  while (len > 0)
5964  {
5965  len--;
5966  if (s1[len] != s2[len])
5967  return false;
5968  }
5969  return true;
5970 }
char * s1
char * s2

◆ split_text()

Datum split_text ( PG_FUNCTION_ARGS  )

Definition at line 4556 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.

4557 {
4558  text *inputstring = PG_GETARG_TEXT_PP(0);
4559  text *fldsep = PG_GETARG_TEXT_PP(1);
4560  int fldnum = PG_GETARG_INT32(2);
4561  int inputstring_len;
4562  int fldsep_len;
4564  char *start_ptr;
4565  char *end_ptr;
4566  text *result_text;
4567  bool found;
4568 
4569  /* field number is 1 based */
4570  if (fldnum < 1)
4571  ereport(ERROR,
4572  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4573  errmsg("field position must be greater than zero")));
4574 
4575  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4576  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4577 
4578  /* return empty string for empty input string */
4579  if (inputstring_len < 1)
4581 
4582  /* empty field separator */
4583  if (fldsep_len < 1)
4584  {
4585  text_position_cleanup(&state);
4586  /* if first field, return input string, else empty string */
4587  if (fldnum == 1)
4588  PG_RETURN_TEXT_P(inputstring);
4589  else
4591  }
4592 
4593  text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4594 
4595  /* identify bounds of first field */
4596  start_ptr = VARDATA_ANY(inputstring);
4597  found = text_position_next(&state);
4598 
4599  /* special case if fldsep not found at all */
4600  if (!found)
4601  {
4602  text_position_cleanup(&state);
4603  /* if field 1 requested, return input string, else empty string */
4604  if (fldnum == 1)
4605  PG_RETURN_TEXT_P(inputstring);
4606  else
4608  }
4609  end_ptr = text_position_get_match_ptr(&state);
4610 
4611  while (found && --fldnum > 0)
4612  {
4613  /* identify bounds of next field */
4614  start_ptr = end_ptr + fldsep_len;
4615  found = text_position_next(&state);
4616  if (found)
4617  end_ptr = text_position_get_match_ptr(&state);
4618  }
4619 
4620  text_position_cleanup(&state);
4621 
4622  if (fldnum > 0)
4623  {
4624  /* N'th field separator not found */
4625  /* if last field requested, return it, else empty string */
4626  if (fldnum == 1)
4627  {
4628  int last_len = start_ptr - VARDATA_ANY(inputstring);
4629 
4630  result_text = cstring_to_text_with_len(start_ptr,
4631  inputstring_len - last_len);
4632  }
4633  else
4634  result_text = cstring_to_text("");
4635  }
4636  else
4637  {
4638  /* non-last field requested */
4639  result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4640  }
4641 
4642  PG_RETURN_TEXT_P(result_text);
4643 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int errcode(int sqlerrcode)
Definition: elog.c:570
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1277
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1410
#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:1439
#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:1151
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:784
Definition: c.h:549

◆ SplitDirectoriesString()

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

Definition at line 3796 of file varlena.c.

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

Referenced by load_libraries(), and PostmasterMain().

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

◆ SplitGUCList()

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

Definition at line 3917 of file varlena.c.

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

Referenced by dumpFunc(), and pg_get_functiondef().

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

◆ SplitIdentifierString()

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

Definition at line 3669 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().

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

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 5171 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.

5172 {
5173  StringInfo state;
5174 
5175  /* cannot be called directly because of internal-type argument */
5176  Assert(AggCheckCallContext(fcinfo, NULL));
5177 
5178  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5179 
5180  if (state != NULL)
5182  else
5183  PG_RETURN_NULL();
5184 }
StringInfoData * StringInfo
Definition: stringinfo.h:43
#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:732
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:3572
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 5145 of file varlena.c.

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

5146 {
5147  StringInfo state;
5148 
5149  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5150 
5151  /* Append the value unless null. */
5152  if (!PG_ARGISNULL(1))
5153  {
5154  /* On the first time through, we ignore the delimiter. */
5155  if (state == NULL)
5156  state = makeStringAggState(fcinfo);
5157  else if (!PG_ARGISNULL(2))
5158  appendStringInfoText(state, PG_GETARG_TEXT_PP(2)); /* delimiter */
5159 
5160  appendStringInfoText(state, PG_GETARG_TEXT_PP(1)); /* value */
5161  }
5162 
5163  /*
5164  * The transition type for string_agg() is declared to be "internal",
5165  * which is a pass-by-value type the same size as a pointer.
5166  */
5167  PG_RETURN_POINTER(state);
5168 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:351
StringInfoData * StringInfo
Definition: stringinfo.h:43
#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:4194
ts_parserstate state
Definition: tsquery.c:81
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5121

◆ 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:555
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:924
Definition: c.h:549
#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 1684 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().

1685 {
1686  char *a1p,
1687  *a2p;
1688  int len1,
1689  len2;
1690 
1691  a1p = VARDATA_ANY(arg1);
1692  a2p = VARDATA_ANY(arg2);
1693 
1694  len1 = VARSIZE_ANY_EXHDR(arg1);
1695  len2 = VARSIZE_ANY_EXHDR(arg2);
1696 
1697  return varstr_cmp(a1p, len1, a2p, len2, collid);
1698 }
#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:1468
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 5311 of file varlena.c.

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

5312 {
5313  text *result;
5314 
5315  result = concat_internal("", 0, fcinfo);
5316  if (result == NULL)
5317  PG_RETURN_NULL();
5318  PG_RETURN_TEXT_P(result);
5319 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5231
Definition: c.h:549
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5326 of file varlena.c.

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

5327 {
5328  char *sep;
5329  text *result;
5330 
5331  /* return NULL when separator is NULL */
5332  if (PG_ARGISNULL(0))
5333  PG_RETURN_NULL();
5335 
5336  result = concat_internal(sep, 1, fcinfo);
5337  if (result == NULL)
5338  PG_RETURN_NULL();
5339  PG_RETURN_TEXT_P(result);
5340 }
#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:5231
char * text_to_cstring(const text *t)
Definition: varlena.c:204
Definition: c.h:549
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

Definition at line 5447 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().

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

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

Referenced by text_format_string_conversion().

5901 {
5902  bool align_to_left = false;
5903  int len;
5904 
5905  /* fast path for typical easy case */
5906  if (width == 0)
5907  {
5909  return;
5910  }
5911 
5912  if (width < 0)
5913  {
5914  /* Negative width: implicit '-' flag, then take absolute value */
5915  align_to_left = true;
5916  /* -INT_MIN is undefined */
5917  if (width <= INT_MIN)
5918  ereport(ERROR,
5919  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5920  errmsg("number is out of range")));
5921  width = -width;
5922  }
5923  else if (flags & TEXT_FORMAT_FLAG_MINUS)
5924  align_to_left = true;
5925 
5926  len = pg_mbstrlen(str);
5927  if (align_to_left)
5928  {
5929  /* left justify */
5931  if (len < width)
5932  appendStringInfoSpaces(buf, width - len);
5933  }
5934  else
5935  {
5936  /* right justify */
5937  if (len < width)
5938  appendStringInfoSpaces(buf, width - len);
5940  }
5941 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:193
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:766
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5432

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 5951 of file varlena.c.

References text_format().

5952 {
5953  return text_format(fcinfo);
5954 }
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5447

◆ text_format_parse_digits()

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

Definition at line 5724 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().

5725 {
5726  bool found = false;
5727  const char *cp = *ptr;
5728  int val = 0;
5729 
5730  while (*cp >= '0' && *cp <= '9')
5731  {
5732  int8 digit = (*cp - '0');
5733 
5734  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5735  unlikely(pg_add_s32_overflow(val, digit, &val)))
5736  ereport(ERROR,
5737  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5738  errmsg("number is out of range")));
5739  ADVANCE_PARSE_POINTER(cp, end_ptr);
5740  found = true;
5741  }
5742 
5743  *ptr = cp;
5744  *value = val;
5745 
5746  return found;
5747 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5434
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140
static struct @144 value
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
signed char int8
Definition: c.h:344
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:784
#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 5773 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().

5776 {
5777  const char *cp = start_ptr;
5778  int n;
5779 
5780  /* set defaults for output parameters */
5781  *argpos = -1;
5782  *widthpos = -1;
5783  *flags = 0;
5784  *width = 0;
5785 
5786  /* try to identify first number */
5787  if (text_format_parse_digits(&cp, end_ptr, &n))
5788  {
5789  if (*cp != '$')
5790  {
5791  /* Must be just a width and a type, so we're done */
5792  *width = n;
5793  return cp;
5794  }
5795  /* The number was argument position */
5796  *argpos = n;
5797  /* Explicit 0 for argument index is immediately refused */
5798  if (n == 0)
5799  ereport(ERROR,
5800  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5801  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5802  ADVANCE_PARSE_POINTER(cp, end_ptr);
5803  }
5804 
5805  /* Handle flags (only minus is supported now) */
5806  while (*cp == '-')
5807  {
5808  *flags |= TEXT_FORMAT_FLAG_MINUS;
5809  ADVANCE_PARSE_POINTER(cp, end_ptr);
5810  }
5811 
5812  if (*cp == '*')
5813  {
5814  /* Handle indirect width */
5815  ADVANCE_PARSE_POINTER(cp, end_ptr);
5816  if (text_format_parse_digits(&cp, end_ptr, &n))
5817  {
5818  /* number in this position must be closed by $ */
5819  if (*cp != '$')
5820  ereport(ERROR,
5821  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5822  errmsg("width argument position must be ended by \"$\"")));
5823  /* The number was width argument position */
5824  *widthpos = n;
5825  /* Explicit 0 for argument index is immediately refused */
5826  if (n == 0)
5827  ereport(ERROR,
5828  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5829  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5830  ADVANCE_PARSE_POINTER(cp, end_ptr);
5831  }
5832  else
5833  *widthpos = 0; /* width's argument position is unspecified */
5834  }
5835  else
5836  {
5837  /* Check for direct width specification */
5838  if (text_format_parse_digits(&cp, end_ptr, &n))
5839  *width = n;
5840  }
5841 
5842  /* cp should now be pointing at type character */
5843  return cp;
5844 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5434
int errcode(int sqlerrcode)
Definition: elog.c:570
#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:5724
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5432

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

5854 {
5855  char *str;
5856 
5857  /* Handle NULL arguments before trying to stringify the value. */
5858  if (isNull)
5859  {
5860  if (conversion == 's')
5861  text_format_append_string(buf, "", flags, width);
5862  else if (conversion == 'L')
5863  text_format_append_string(buf, "NULL", flags, width);
5864  else if (conversion == 'I')
5865  ereport(ERROR,
5866  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5867  errmsg("null values cannot be formatted as an SQL identifier")));
5868  return;
5869  }
5870 
5871  /* Stringify. */
5872  str = OutputFunctionCall(typOutputInfo, value);
5873 
5874  /* Escape. */
5875  if (conversion == 'I')
5876  {
5877  /* quote_identifier may or may not allocate a new string. */
5878  text_format_append_string(buf, quote_identifier(str), flags, width);
5879  }
5880  else if (conversion == 'L')
5881  {
5882  char *qstr = quote_literal_cstr(str);
5883 
5884  text_format_append_string(buf, qstr, flags, width);
5885  /* quote_literal_cstr() always allocates a new string */
5886  pfree(qstr);
5887  }
5888  else
5889  text_format_append_string(buf, str, flags, width);
5890 
5891  /* Cleanup. */
5892  pfree(str);
5893 }
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:102
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10628
static struct @144 value
int errcode(int sqlerrcode)
Definition: elog.c:570
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:5899
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

Definition at line 1856 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().

1857 {
1858  text *arg1 = PG_GETARG_TEXT_PP(0);
1859  text *arg2 = PG_GETARG_TEXT_PP(1);
1860  bool result;
1861 
1862  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1863 
1864  PG_FREE_IF_COPY(arg1, 0);
1865  PG_FREE_IF_COPY(arg2, 1);
1866 
1867  PG_RETURN_BOOL(result);
1868 }
#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:1684
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

Definition at line 1841 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().

1842 {
1843  text *arg1 = PG_GETARG_TEXT_PP(0);
1844  text *arg2 = PG_GETARG_TEXT_PP(1);
1845  bool result;
1846 
1847  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1848 
1849  PG_FREE_IF_COPY(arg1, 0);
1850  PG_FREE_IF_COPY(arg2, 1);
1851 
1852  PG_RETURN_BOOL(result);
1853 }
#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:1684
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ text_isequal()

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

Definition at line 4649 of file varlena.c.

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

Referenced by text_to_array_internal().

4650 {
4652  collid,
4653  PointerGetDatum(txt1),
4654  PointerGetDatum(txt2)));
4655 }
#define PointerGetDatum(X)
Definition: postgres.h:556
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1709
#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 2773 of file varlena.c.

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

2774 {
2775  text *arg1 = PG_GETARG_TEXT_PP(0);
2776  text *arg2 = PG_GETARG_TEXT_PP(1);
2777  text *result;
2778 
2779  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2780 
2781  PG_RETURN_TEXT_P(result);
2782 }
#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:1684
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:361
Definition: c.h:549

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

Definition at line 1826 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().

1827 {
1828  text *arg1 = PG_GETARG_TEXT_PP(0);
1829  text *arg2 = PG_GETARG_TEXT_PP(1);
1830  bool result;
1831 
1832  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1833 
1834  PG_FREE_IF_COPY(arg1, 0);
1835  PG_FREE_IF_COPY(arg2, 1);
1836 
1837  PG_RETURN_BOOL(result);
1838 }
#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:1684
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

Definition at line 5347 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.

5348 {
5349  int n = PG_GETARG_INT32(1);
5350 
5351  if (n < 0)
5352  {
5353  text *str = PG_GETARG_TEXT_PP(0);
5354  const char *p = VARDATA_ANY(str);
5355  int len = VARSIZE_ANY_EXHDR(str);
5356  int rlen;
5357 
5358  n = pg_mbstrlen_with_len(p, len) + n;
5359  rlen = pg_mbcharcliplen(p, len, n);
5361  }
5362  else
5364 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:854
#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:786
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:549

◆ 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:555
#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:786
int pg_database_encoding_max_length(void)
Definition: wchar.c:1881
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:768
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:549

◆ text_lt()

Datum text_lt ( PG_FUNCTION_ARGS  )

Definition at line 1811 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().

1812 {
1813  text *arg1 = PG_GETARG_TEXT_PP(0);
1814  text *arg2 = PG_GETARG_TEXT_PP(1);
1815  bool result;
1816 
1817  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
1818 
1819  PG_FREE_IF_COPY(arg1, 0);
1820  PG_FREE_IF_COPY(arg2, 1);
1821 
1822  PG_RETURN_BOOL(result);
1823 }
#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:1684
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549

◆ text_name()

Datum text_name ( PG_FUNCTION_ARGS  )

Definition at line 3571 of file varlena.c.

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

3572 {
3573  text *s = PG_GETARG_TEXT_PP(0);
3574  Name result;
3575  int len;
3576 
3577  len = VARSIZE_ANY_EXHDR(s);
3578 
3579  /* Truncate oversize input */
3580  if (len >= NAMEDATALEN)
3581  len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1);
3582 
3583  /* We use palloc0 here to ensure result is zero-padded */
3584  result = (Name) palloc0(NAMEDATALEN);
3585  memcpy(NameStr(*result), VARDATA_ANY(s), len);
3586 
3587  PG_RETURN_NAME(result);
3588 }
#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:812
Definition: c.h:603
void * palloc0(Size size)
Definition: mcxt.c:955
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:609
Definition: c.h:549
NameData * Name
Definition: c.h:607
#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:570
#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:784
Definition: c.h:549

◆ text_pattern_ge()

Datum text_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 3075 of file varlena.c.

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

3076 {
3077  text *arg1 = PG_GETARG_TEXT_PP(0);
3078  text *arg2 = PG_GETARG_TEXT_PP(1);
3079  int result;
3080 
3081  result = internal_text_pattern_compare(arg1, arg2, PG_GET_COLLATION());
3082 
3083  PG_FREE_IF_COPY(arg1, 0);
3084  PG_FREE_IF_COPY(arg2, 1);
3085 
3086  PG_RETURN_BOOL(result >= 0);
3087 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549
static int internal_text_pattern_compare(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:2999

◆ text_pattern_gt()

Datum text_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 3091 of file varlena.c.

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

3092 {
3093  text *arg1 = PG_GETARG_TEXT_PP(0);
3094  text *arg2 = PG_GETARG_TEXT_PP(1);
3095  int result;
3096 
3097  result = internal_text_pattern_compare(arg1, arg2, PG_GET_COLLATION());
3098 
3099  PG_FREE_IF_COPY(arg1, 0);
3100  PG_FREE_IF_COPY(arg2, 1);
3101 
3102  PG_RETURN_BOOL(result > 0);
3103 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549
static int internal_text_pattern_compare(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:2999

◆ text_pattern_le()

Datum text_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 3059 of file varlena.c.

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

3060 {
3061  text *arg1 = PG_GETARG_TEXT_PP(0);
3062  text *arg2 = PG_GETARG_TEXT_PP(1);
3063  int result;
3064 
3065  result = internal_text_pattern_compare(arg1, arg2, PG_GET_COLLATION());
3066 
3067  PG_FREE_IF_COPY(arg1, 0);
3068  PG_FREE_IF_COPY(arg2, 1);
3069 
3070  PG_RETURN_BOOL(result <= 0);
3071 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549
static int internal_text_pattern_compare(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:2999

◆ text_pattern_lt()

Datum text_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 3043 of file varlena.c.

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

3044 {
3045  text *arg1 = PG_GETARG_TEXT_PP(0);
3046  text *arg2 = PG_GETARG_TEXT_PP(1);
3047  int result;
3048 
3049  result = internal_text_pattern_compare(arg1, arg2, PG_GET_COLLATION());
3050 
3051  PG_FREE_IF_COPY(arg1, 0);
3052  PG_FREE_IF_COPY(arg2, 1);
3053 
3054  PG_RETURN_BOOL(result < 0);
3055 }
#define PG_GET_COLLATION()
Definition: fmgr.h:193
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
Definition: c.h:549
static int internal_text_pattern_compare(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:2999

◆ 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  if (VARSIZE_ANY_EXHDR(t1) < 1 || VARSIZE_ANY_EXHDR(t2) < 1)
1122  return 0;
1123 
1124  text_position_setup(t1, t2, collid, &state);
1125  if (!text_position_next(&state))
1126  result = 0;
1127  else
1128  result = text_position_get_match_pos(&state);
1129  text_position_cleanup(&state);
1130  return result;
1131 }
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1277
static int text_position_get_match_pos(TextPositionState *state)
Definition: varlena.c:1421
ts_parserstate state
Definition: tsquery.c:81
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1439
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1151
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ text_position_cleanup()

static void text_position_cleanup ( TextPositionState state)
static

Definition at line 1439 of file varlena.c.

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

1440 {
1441  /* no cleanup needed */
1442 }

◆ text_position_get_match_pos()

static int text_position_get_match_pos ( TextPositionState state)
static

Definition at line 1421 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().

1422 {
1423  if (!state->is_multibyte)
1424  return state->last_match - state->str1 + 1;
1425  else
1426  {
1427  /* Convert the byte position to char position. */
1428  while (state->refpoint < state->last_match)
1429  {
1430  state->refpoint += pg_mblen(state->refpoint);
1431  state->refpos++;
1432  }
1433  Assert(state->refpoint == state->last_match);
1434  return state->refpos + 1;
1435  }
1436 }
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:732
int pg_mblen(const char *mbstr)
Definition: mbutils.c:752

◆ text_position_get_match_ptr()

static char * text_position_get_match_ptr ( TextPositionState state)
static

Definition at line 1410 of file varlena.c.

References TextPositionState::last_match.

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

1411 {
1412  return state->last_match;
1413 }
char * last_match
Definition: varlena.c:63

◆ text_position_next()

static bool text_position_next ( TextPositionState state)
static

Definition at line 1277 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().

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

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

Referenced by text_position_next().

1342 {
1343  int haystack_len = state->len1;
1344  int needle_len = state->len2;
1345  int skiptablemask = state->skiptablemask;
1346  const char *haystack = state->str1;
1347  const char *needle = state->str2;
1348  const char *haystack_end = &haystack[haystack_len];
1349  const char *hptr;
1350 
1351  Assert(start_ptr >= haystack && start_ptr <= haystack_end);
1352 
1353  if (needle_len == 1)
1354  {
1355  /* No point in using B-M-H for a one-character needle */
1356  char nchar = *needle;
1357 
1358  hptr = start_ptr;
1359  while (hptr < haystack_end)
1360  {
1361  if (*hptr == nchar)
1362  return (char *) hptr;
1363  hptr++;
1364  }
1365  }
1366  else