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/hashfn.h"
#include "common/int.h"
#include "common/unicode_norm.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/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 btvarstrequalimage (PG_FUNCTION_ARGS)
 
Datum text_larger (PG_FUNCTION_ARGS)
 
Datum text_smaller (PG_FUNCTION_ARGS)
 
Datum nameeqtext (PG_FUNCTION_ARGS)
 
Datum texteqname (PG_FUNCTION_ARGS)
 
Datum namenetext (PG_FUNCTION_ARGS)
 
Datum textnename (PG_FUNCTION_ARGS)
 
Datum btnametextcmp (PG_FUNCTION_ARGS)
 
Datum bttextnamecmp (PG_FUNCTION_ARGS)
 
Datum namelttext (PG_FUNCTION_ARGS)
 
Datum nameletext (PG_FUNCTION_ARGS)
 
Datum namegttext (PG_FUNCTION_ARGS)
 
Datum namegetext (PG_FUNCTION_ARGS)
 
Datum textltname (PG_FUNCTION_ARGS)
 
Datum textlename (PG_FUNCTION_ARGS)
 
Datum textgtname (PG_FUNCTION_ARGS)
 
Datum textgename (PG_FUNCTION_ARGS)
 
static int internal_text_pattern_compare (text *arg1, text *arg2)
 
Datum text_pattern_lt (PG_FUNCTION_ARGS)
 
Datum text_pattern_le (PG_FUNCTION_ARGS)
 
Datum text_pattern_ge (PG_FUNCTION_ARGS)
 
Datum text_pattern_gt (PG_FUNCTION_ARGS)
 
Datum bttext_pattern_cmp (PG_FUNCTION_ARGS)
 
Datum bttext_pattern_sortsupport (PG_FUNCTION_ARGS)
 
Datum byteaoctetlen (PG_FUNCTION_ARGS)
 
Datum byteacat (PG_FUNCTION_ARGS)
 
Datum bytea_substr (PG_FUNCTION_ARGS)
 
Datum bytea_substr_no_len (PG_FUNCTION_ARGS)
 
Datum byteaoverlay (PG_FUNCTION_ARGS)
 
Datum byteaoverlay_no_len (PG_FUNCTION_ARGS)
 
Datum 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)
 
static UnicodeNormalizationForm unicode_norm_form_from_string (const char *formstr)
 
Datum unicode_normalize_func (PG_FUNCTION_ARGS)
 
Datum unicode_is_normalized (PG_FUNCTION_ARGS)
 

Variables

int bytea_output = BYTEA_OUTPUT_HEX
 

Macro Definition Documentation

◆ ADVANCE_PARSE_POINTER

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

Definition at line 5451 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:268
#define PG_GET_COLLATION()
Definition: fmgr.h:198
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:815

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

◆ DatumGetUnknownPCopy

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

Definition at line 102 of file varlena.c.

◆ DatumGetVarStringP

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

Definition at line 107 of file varlena.c.

◆ DatumGetVarStringPP

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

Definition at line 108 of file varlena.c.

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

◆ DIG

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

Definition at line 264 of file varlena.c.

Referenced by byteaout().

◆ HEXBASE

#define HEXBASE   16

Definition at line 5029 of file varlena.c.

Referenced by to_hex32(), and to_hex64().

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

Definition at line 5991 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P

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

Definition at line 103 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P_COPY

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

Definition at line 104 of file varlena.c.

◆ PG_RETURN_UNKNOWN_P

#define PG_RETURN_UNKNOWN_P (   x)    PG_RETURN_POINTER(x)

Definition at line 105 of file varlena.c.

◆ PG_STR_GET_BYTEA

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

Definition at line 3234 of file varlena.c.

Referenced by bytea_substring().

◆ REGEXP_REPLACE_BACKREF_CNT

#define REGEXP_REPLACE_BACKREF_CNT   10

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

Referenced by text_format_append_string(), and text_format_parse_format().

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 99 of file varlena.c.

Referenced by varstr_cmp(), and varstr_sortsupport().

◆ VAL

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

Definition at line 263 of file varlena.c.

Referenced by byteain().

Typedef Documentation

◆ unknown

typedef struct varlena unknown

Definition at line 44 of file varlena.c.

◆ VarString

typedef struct varlena VarString

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

4336 {
4337  const char *p = VARDATA_ANY(replace_text);
4338  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4339  int eml = pg_database_encoding_max_length();
4340 
4341  for (;;)
4342  {
4343  const char *chunk_start = p;
4344  int so;
4345  int eo;
4346 
4347  /* Find next escape char. */
4348  if (eml == 1)
4349  {
4350  for (; p < p_end && *p != '\\'; p++)
4351  /* nothing */ ;
4352  }
4353  else
4354  {
4355  for (; p < p_end && *p != '\\'; p += pg_mblen(p))
4356  /* nothing */ ;
4357  }
4358 
4359  /* Copy the text we just scanned over, if any. */
4360  if (p > chunk_start)
4361  appendBinaryStringInfo(str, chunk_start, p - chunk_start);
4362 
4363  /* Done if at end of string, else advance over escape char. */
4364  if (p >= p_end)
4365  break;
4366  p++;
4367 
4368  if (p >= p_end)
4369  {
4370  /* Escape at very end of input. Treat same as unexpected char */
4371  appendStringInfoChar(str, '\\');
4372  break;
4373  }
4374 
4375  if (*p >= '1' && *p <= '9')
4376  {
4377  /* Use the back reference of regexp. */
4378  int idx = *p - '0';
4379 
4380  so = pmatch[idx].rm_so;
4381  eo = pmatch[idx].rm_eo;
4382  p++;
4383  }
4384  else if (*p == '&')
4385  {
4386  /* Use the entire matched string. */
4387  so = pmatch[0].rm_so;
4388  eo = pmatch[0].rm_eo;
4389  p++;
4390  }
4391  else if (*p == '\\')
4392  {
4393  /* \\ means transfer one \ to output. */
4394  appendStringInfoChar(str, '\\');
4395  p++;
4396  continue;
4397  }
4398  else
4399  {
4400  /*
4401  * If escape char is not followed by any expected char, just treat
4402  * it as ordinary data to copy. (XXX would it be better to throw
4403  * an error?)
4404  */
4405  appendStringInfoChar(str, '\\');
4406  continue;
4407  }
4408 
4409  if (so != -1 && eo != -1)
4410  {
4411  /*
4412  * Copy the text that is back reference of regexp. Note so and eo
4413  * are counted in characters not bytes.
4414  */
4415  char *chunk_start;
4416  int chunk_len;
4417 
4418  Assert(so >= data_pos);
4419  chunk_start = start_ptr;
4420  chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
4421  chunk_len = charlen_to_bytelen(chunk_start, eo - so);
4422  appendBinaryStringInfo(str, chunk_start, chunk_len);
4423  }
4424  }
4425 }
#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:259
regoff_t rm_eo
Definition: regex.h:86
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:769
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
#define Assert(condition)
Definition: c.h:738
int pg_mblen(const char *mbstr)
Definition: mbutils.c:907
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1436
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ appendStringInfoText()

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

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

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

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

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

4871 {
4873  char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4874 
4875  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4876 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#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:4912
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
char * text_to_cstring(const text *t)
Definition: varlena.c:205

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

4914 {
4915  text *result;
4916  int nitems,
4917  *dims,
4918  ndims;
4919  Oid element_type;
4920  int typlen;
4921  bool typbyval;
4922  char typalign;
4924  bool printed = false;
4925  char *p;
4926  bits8 *bitmap;
4927  int bitmask;
4928  int i;
4929  ArrayMetaState *my_extra;
4930 
4931  ndims = ARR_NDIM(v);
4932  dims = ARR_DIMS(v);
4933  nitems = ArrayGetNItems(ndims, dims);
4934 
4935  /* if there are no elements, return an empty string */
4936  if (nitems == 0)
4937  return cstring_to_text_with_len("", 0);
4938 
4939  element_type = ARR_ELEMTYPE(v);
4940  initStringInfo(&buf);
4941 
4942  /*
4943  * We arrange to look up info about element type, including its output
4944  * conversion proc, only once per series of calls, assuming the element
4945  * type doesn't change underneath us.
4946  */
4947  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4948  if (my_extra == NULL)
4949  {
4950  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4951  sizeof(ArrayMetaState));
4952  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4953  my_extra->element_type = ~element_type;
4954  }
4955 
4956  if (my_extra->element_type != element_type)
4957  {
4958  /*
4959  * Get info about element type, including its output conversion proc
4960  */
4961  get_type_io_data(element_type, IOFunc_output,
4962  &my_extra->typlen, &my_extra->typbyval,
4963  &my_extra->typalign, &my_extra->typdelim,
4964  &my_extra->typioparam, &my_extra->typiofunc);
4965  fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
4966  fcinfo->flinfo->fn_mcxt);
4967  my_extra->element_type = element_type;
4968  }
4969  typlen = my_extra->typlen;
4970  typbyval = my_extra->typbyval;
4971  typalign = my_extra->typalign;
4972 
4973  p = ARR_DATA_PTR(v);
4974  bitmap = ARR_NULLBITMAP(v);
4975  bitmask = 1;
4976 
4977  for (i = 0; i < nitems; i++)
4978  {
4979  Datum itemvalue;
4980  char *value;
4981 
4982  /* Get source element, checking for NULL */
4983  if (bitmap && (*bitmap & bitmask) == 0)
4984  {
4985  /* if null_string is NULL, we just ignore null elements */
4986  if (null_string != NULL)
4987  {
4988  if (printed)
4989  appendStringInfo(&buf, "%s%s", fldsep, null_string);
4990  else
4991  appendStringInfoString(&buf, null_string);
4992  printed = true;
4993  }
4994  }
4995  else
4996  {
4997  itemvalue = fetch_att(p, typbyval, typlen);
4998 
4999  value = OutputFunctionCall(&my_extra->proc, itemvalue);
5000 
5001  if (printed)
5002  appendStringInfo(&buf, "%s%s", fldsep, value);
5003  else
5004  appendStringInfoString(&buf, value);
5005  printed = true;
5006 
5007  p = att_addlength_pointer(p, typlen, p);
5008  p = (char *) att_align_nominal(p, typalign);
5009  }
5010 
5011  /* advance bitmap pointer if any */
5012  if (bitmap)
5013  {
5014  bitmask <<= 1;
5015  if (bitmask == 0x100)
5016  {
5017  bitmap++;
5018  bitmask = 1;
5019  }
5020  }
5021  }
5022 
5023  result = cstring_to_text_with_len(buf.data, buf.len);
5024  pfree(buf.data);
5025 
5026  return result;
5027 }
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:75
unsigned int Oid
Definition: postgres_ext.h:31
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1577
bool typbyval
Definition: array.h:228
void pfree(void *pointer)
Definition: mcxt.c:1056
char typalign
Definition: pg_type.h:170
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ARR_DIMS(a)
Definition: array.h:282
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define ARR_DATA_PTR(a)
Definition: array.h:310
int16 typlen
Definition: array.h:227
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
char typdelim
Definition: array.h:230
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uint8 bits8
Definition: c.h:374
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * flinfo
Definition: fmgr.h:87
static struct @143 value
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:75
FmgrInfo proc
Definition: array.h:233
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
int i
Oid element_type
Definition: array.h:226
Definition: c.h:555
#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:2213

◆ array_to_text_null()

Datum array_to_text_null ( PG_FUNCTION_ARGS  )

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

4887 {
4888  ArrayType *v;
4889  char *fldsep;
4890  char *null_string;
4891 
4892  /* returns NULL when first or second parameter is NULL */
4893  if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4894  PG_RETURN_NULL();
4895 
4896  v = PG_GETARG_ARRAYTYPE_P(0);
4897  fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4898 
4899  /* NULL null string is passed through as a null pointer */
4900  if (!PG_ARGISNULL(2))
4901  null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
4902  else
4903  null_string = NULL;
4904 
4905  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
4906 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#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:4912
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
char * text_to_cstring(const text *t)
Definition: varlena.c:205
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ bpcharfastcmp_c()

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

Definition at line 2178 of file varlena.c.

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

Referenced by varstr_sortsupport().

2179 {
2180  BpChar *arg1 = DatumGetBpCharPP(x);
2181  BpChar *arg2 = DatumGetBpCharPP(y);
2182  char *a1p,
2183  *a2p;
2184  int len1,
2185  len2,
2186  result;
2187 
2188  a1p = VARDATA_ANY(arg1);
2189  a2p = VARDATA_ANY(arg2);
2190 
2191  len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2192  len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2193 
2194  result = memcmp(a1p, a2p, Min(len1, len2));
2195  if ((result == 0) && (len1 != len2))
2196  result = (len1 < len2) ? -1 : 1;
2197 
2198  /* We can't afford to leak memory here. */
2199  if (PointerGetDatum(arg1) != x)
2200  pfree(arg1);
2201  if (PointerGetDatum(arg2) != y)
2202  pfree(arg2);
2203 
2204  return result;
2205 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PointerGetDatum(X)
Definition: postgres.h:556
#define Min(x, y)
Definition: c.h:920
void pfree(void *pointer)
Definition: mcxt.c:1056
int bpchartruelen(char *s, int len)
Definition: varchar.c:671
#define DatumGetBpCharPP(X)
Definition: fmgr.h:292
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555

◆ btnametextcmp()

Datum btnametextcmp ( PG_FUNCTION_ARGS  )

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

2949 {
2950  Name arg1 = PG_GETARG_NAME(0);
2951  text *arg2 = PG_GETARG_TEXT_PP(1);
2952  int32 result;
2953 
2954  result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
2955  VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
2956  PG_GET_COLLATION());
2957 
2958  PG_FREE_IF_COPY(arg2, 1);
2959 
2960  PG_RETURN_INT32(result);
2961 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:355
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1494
Definition: c.h:609
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:615
Definition: c.h:555
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 3131 of file varlena.c.

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

3132 {
3133  text *arg1 = PG_GETARG_TEXT_PP(0);
3134  text *arg2 = PG_GETARG_TEXT_PP(1);
3135  int result;
3136 
3137  result = internal_text_pattern_compare(arg1, arg2);
3138 
3139  PG_FREE_IF_COPY(arg1, 0);
3140  PG_FREE_IF_COPY(arg2, 1);
3141 
3142  PG_RETURN_INT32(result);
3143 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3045
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 3147 of file varlena.c.

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

3148 {
3150  MemoryContext oldcontext;
3151 
3152  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
3153 
3154  /* Use generic string SortSupport, forcing "C" collation */
3155  varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID);
3156 
3157  MemoryContextSwitchTo(oldcontext);
3158 
3159  PG_RETURN_VOID();
3160 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1979
#define PG_RETURN_VOID()
Definition: fmgr.h:348

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

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

1938 {
1939  text *arg1 = PG_GETARG_TEXT_PP(0);
1940  text *arg2 = PG_GETARG_TEXT_PP(1);
1941  int32 result;
1942 
1943  result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1944 
1945  PG_FREE_IF_COPY(arg1, 0);
1946  PG_FREE_IF_COPY(arg2, 1);
1947 
1948  PG_RETURN_INT32(result);
1949 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:355
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1710
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ bttextnamecmp()

Datum bttextnamecmp ( PG_FUNCTION_ARGS  )

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

2965 {
2966  text *arg1 = PG_GETARG_TEXT_PP(0);
2967  Name arg2 = PG_GETARG_NAME(1);
2968  int32 result;
2969 
2970  result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
2971  NameStr(*arg2), strlen(NameStr(*arg2)),
2972  PG_GET_COLLATION());
2973 
2974  PG_FREE_IF_COPY(arg1, 0);
2975 
2976  PG_RETURN_INT32(result);
2977 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:355
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1494
Definition: c.h:609
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:615
Definition: c.h:555
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1952 of file varlena.c.

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

1953 {
1955  Oid collid = ssup->ssup_collation;
1956  MemoryContext oldcontext;
1957 
1958  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1959 
1960  /* Use generic string SortSupport */
1961  varstr_sortsupport(ssup, TEXTOID, collid);
1962 
1963  MemoryContextSwitchTo(oldcontext);
1964 
1965  PG_RETURN_VOID();
1966 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
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:1979
#define PG_RETURN_VOID()
Definition: fmgr.h:348

◆ btvarstrequalimage()

Datum btvarstrequalimage ( PG_FUNCTION_ARGS  )

Definition at line 2803 of file varlena.c.

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

2804 {
2805  /* Oid opcintype = PG_GETARG_OID(0); */
2806  Oid collid = PG_GET_COLLATION();
2807 
2808  check_collation_set(collid);
2809 
2810  if (lc_collate_is_c(collid) ||
2811  collid == DEFAULT_COLLATION_OID ||
2813  PG_RETURN_BOOL(true);
2814  else
2815  PG_RETURN_BOOL(false);
2816 }
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:1052
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
bool lc_collate_is_c(Oid collation)
Definition: pg_locale.c:1356
static void check_collation_set(Oid collid)
Definition: varlena.c:1465
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358

◆ build_concat_foutcache()

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

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

5211 {
5212  FmgrInfo *foutcache;
5213  int i;
5214 
5215  /* We keep the info in fn_mcxt so it survives across calls */
5216  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5217  PG_NARGS() * sizeof(FmgrInfo));
5218 
5219  for (i = argidx; i < PG_NARGS(); i++)
5220  {
5221  Oid valtype;
5222  Oid typOutput;
5223  bool typIsVarlena;
5224 
5225  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5226  if (!OidIsValid(valtype))
5227  elog(ERROR, "could not determine data type of concat() input");
5228 
5229  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5230  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5231  }
5232 
5233  fcinfo->flinfo->fn_extra = foutcache;
5234 
5235  return foutcache;
5236 }
Definition: fmgr.h:56
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2784
MemoryContext fn_mcxt
Definition: fmgr.h:65
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1804
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
FmgrInfo * flinfo
Definition: fmgr.h:87
struct FmgrInfo FmgrInfo
#define PG_NARGS()
Definition: fmgr.h:203
void * fn_extra
Definition: fmgr.h:64
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:214
int i

◆ bytea_catenate()

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

Definition at line 3201 of file varlena.c.

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

Referenced by bytea_overlay(), and byteacat().

3202 {
3203  bytea *result;
3204  int len1,
3205  len2,
3206  len;
3207  char *ptr;
3208 
3209  len1 = VARSIZE_ANY_EXHDR(t1);
3210  len2 = VARSIZE_ANY_EXHDR(t2);
3211 
3212  /* paranoia ... probably should throw error instead? */
3213  if (len1 < 0)
3214  len1 = 0;
3215  if (len2 < 0)
3216  len2 = 0;
3217 
3218  len = len1 + len2 + VARHDRSZ;
3219  result = (bytea *) palloc(len);
3220 
3221  /* Set size of result string... */
3222  SET_VARSIZE(result, len);
3223 
3224  /* Fill data field of result string... */
3225  ptr = VARDATA(result);
3226  if (len1 > 0)
3227  memcpy(ptr, VARDATA_ANY(t1), len1);
3228  if (len2 > 0)
3229  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
3230 
3231  return result;
3232 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:561
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:555
#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 3358 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().

3359 {
3360  bytea *result;
3361  bytea *s1;
3362  bytea *s2;
3363  int sp_pl_sl;
3364 
3365  /*
3366  * Check for possible integer-overflow cases. For negative sp, throw a
3367  * "substring length" error because that's what should be expected
3368  * according to the spec's definition of OVERLAY().
3369  */
3370  if (sp <= 0)
3371  ereport(ERROR,
3372  (errcode(ERRCODE_SUBSTRING_ERROR),
3373  errmsg("negative substring length not allowed")));
3374  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
3375  ereport(ERROR,
3376  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3377  errmsg("integer out of range")));
3378 
3379  s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
3380  s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
3381  result = bytea_catenate(s1, t2);
3382  result = bytea_catenate(result, s2);
3383 
3384  return result;
3385 }
#define PointerGetDatum(X)
Definition: postgres.h:556
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3201
int errcode(int sqlerrcode)
Definition: elog.c:610
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3276
#define ERROR
Definition: elog.h:43
char * s1
char * s2
#define ereport(elevel,...)
Definition: elog.h:144
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 4189 of file varlena.c.

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

4190 {
4192  MemoryContext oldcontext;
4193 
4194  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
4195 
4196  /* Use generic string SortSupport, forcing "C" collation */
4197  varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
4198 
4199  MemoryContextSwitchTo(oldcontext);
4200 
4201  PG_RETURN_VOID();
4202 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1979
#define PG_RETURN_VOID()
Definition: fmgr.h:348

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

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

517 {
519 
520  /* cannot be called directly because of internal-type argument */
521  Assert(AggCheckCallContext(fcinfo, NULL));
522 
523  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
524 
525  if (state != NULL)
526  {
527  bytea *result;
528 
529  result = (bytea *) palloc(state->len + VARHDRSZ);
530  SET_VARSIZE(result, state->len + VARHDRSZ);
531  memcpy(VARDATA(result), state->data, state->len);
532  PG_RETURN_BYTEA_P(result);
533  }
534  else
535  PG_RETURN_NULL();
536 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:561
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
ts_parserstate state
Definition: tsquery.c:81
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:738
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4684
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:555
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

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

485 {
487 
488  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
489 
490  /* Append the value unless null. */
491  if (!PG_ARGISNULL(1))
492  {
494 
495  /* On the first time through, we ignore the delimiter. */
496  if (state == NULL)
497  state = makeStringAggState(fcinfo);
498  else if (!PG_ARGISNULL(2))
499  {
500  bytea *delim = PG_GETARG_BYTEA_PP(2);
501 
503  }
504 
506  }
507 
508  /*
509  * The transition type for string_agg() is declared to be "internal",
510  * which is a pass-by-value type the same size as a pointer.
511  */
512  PG_RETURN_POINTER(state);
513 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:360
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
ts_parserstate state
Definition: tsquery.c:81
static struct @143 value
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5138
Definition: c.h:555
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 3253 of file varlena.c.

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

3254 {
3256  PG_GETARG_INT32(1),
3257  PG_GETARG_INT32(2),
3258  false));
3259 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3276

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3267 of file varlena.c.

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

3268 {
3270  PG_GETARG_INT32(1),
3271  -1,
3272  true));
3273 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3276

◆ bytea_substring()

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

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

3280 {
3281  int S1; /* adjusted start position */
3282  int L1; /* adjusted substring length */
3283 
3284  S1 = Max(S, 1);
3285 
3286  if (length_not_specified)
3287  {
3288  /*
3289  * Not passed a length - DatumGetByteaPSlice() grabs everything to the
3290  * end of the string if we pass it a negative value for length.
3291  */
3292  L1 = -1;
3293  }
3294  else
3295  {
3296  /* end position */
3297  int E = S + L;
3298 
3299  /*
3300  * A negative value for L is the only way for the end position to be
3301  * before the start. SQL99 says to throw an error.
3302  */
3303  if (E < S)
3304  ereport(ERROR,
3305  (errcode(ERRCODE_SUBSTRING_ERROR),
3306  errmsg("negative substring length not allowed")));
3307 
3308  /*
3309  * A zero or negative value for the end position can happen if the
3310  * start was negative or one. SQL99 says to return a zero-length
3311  * string.
3312  */
3313  if (E < 1)
3314  return PG_STR_GET_BYTEA("");
3315 
3316  L1 = E - S1;
3317  }
3318 
3319  /*
3320  * If the start position is past the end of the string, SQL99 says to
3321  * return a zero-length string -- DatumGetByteaPSlice() will do that for
3322  * us. Convert to zero-based starting position
3323  */
3324  return DatumGetByteaPSlice(str, S1 - 1, L1);
3325 }
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:302
int errcode(int sqlerrcode)
Definition: elog.c:610
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:3234
#define ERROR
Definition: elog.h:43
#define S(n, x)
Definition: sha1.c:55
#define ereport(elevel,...)
Definition: elog.h:144
#define Max(x, y)
Definition: c.h:914
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 3186 of file varlena.c.

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

3187 {
3188  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3189  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3190 
3192 }
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3201
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
Definition: c.h:555

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

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

4168 {
4169  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4170  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4171  int len1,
4172  len2;
4173  int cmp;
4174 
4175  len1 = VARSIZE_ANY_EXHDR(arg1);
4176  len2 = VARSIZE_ANY_EXHDR(arg2);
4177 
4178  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4179  if ((cmp == 0) && (len1 != len2))
4180  cmp = (len1 < len2) ? -1 : 1;
4181 
4182  PG_FREE_IF_COPY(arg1, 0);
4183  PG_FREE_IF_COPY(arg2, 1);
4184 
4185  PG_RETURN_INT32(cmp);
4186 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:920
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555
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 4023 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().

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

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

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

4148 {
4149  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4150  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4151  int len1,
4152  len2;
4153  int cmp;
4154 
4155  len1 = VARSIZE_ANY_EXHDR(arg1);
4156  len2 = VARSIZE_ANY_EXHDR(arg2);
4157 
4158  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4159 
4160  PG_FREE_IF_COPY(arg1, 0);
4161  PG_FREE_IF_COPY(arg2, 1);
4162 
4163  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
4164 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:920
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555
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 3467 of file varlena.c.

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

3468 {
3469  bytea *v = PG_GETARG_BYTEA_PP(0);
3470  int64 n = PG_GETARG_INT64(1);
3471  int byteNo,
3472  bitNo;
3473  int len;
3474  int byte;
3475 
3476  len = VARSIZE_ANY_EXHDR(v);
3477 
3478  if (n < 0 || n >= (int64) len * 8)
3479  ereport(ERROR,
3480  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3481  errmsg("index %lld out of valid range, 0..%lld",
3482  (long long) n, (long long) len * 8 - 1)));
3483 
3484  /* n/8 is now known < len, so safe to cast to int */
3485  byteNo = (int) (n / 8);
3486  bitNo = (int) (n % 8);
3487 
3488  byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3489 
3490  if (byte & (1 << bitNo))
3491  PG_RETURN_INT32(1);
3492  else
3493  PG_RETURN_INT32(0);
3494 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
#define byte(x, n)
Definition: rijndael.c:68
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

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

3439 {
3440  bytea *v = PG_GETARG_BYTEA_PP(0);
3441  int32 n = PG_GETARG_INT32(1);
3442  int len;
3443  int byte;
3444 
3445  len = VARSIZE_ANY_EXHDR(v);
3446 
3447  if (n < 0 || n >= len)
3448  ereport(ERROR,
3449  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3450  errmsg("index %d out of valid range, 0..%d",
3451  n, len - 1)));
3452 
3453  byte = ((unsigned char *) VARDATA_ANY(v))[n];
3454 
3455  PG_RETURN_INT32(byte);
3456 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
int errcode(int sqlerrcode)
Definition: elog.c:610
signed int int32
Definition: c.h:355
#define ERROR
Definition: elog.h:43
#define byte(x, n)
Definition: rijndael.c:68
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

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

4128 {
4129  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4130  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4131  int len1,
4132  len2;
4133  int cmp;
4134 
4135  len1 = VARSIZE_ANY_EXHDR(arg1);
4136  len2 = VARSIZE_ANY_EXHDR(arg2);
4137 
4138  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4139 
4140  PG_FREE_IF_COPY(arg1, 0);
4141  PG_FREE_IF_COPY(arg2, 1);
4142 
4143  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
4144 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:920
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555
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 278 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().

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

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

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

4108 {
4109  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4110  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4111  int len1,
4112  len2;
4113  int cmp;
4114 
4115  len1 = VARSIZE_ANY_EXHDR(arg1);
4116  len2 = VARSIZE_ANY_EXHDR(arg2);
4117 
4118  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4119 
4120  PG_FREE_IF_COPY(arg1, 0);
4121  PG_FREE_IF_COPY(arg2, 1);
4122 
4123  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
4124 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:920
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555
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 4087 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().

4088 {
4089  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4090  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4091  int len1,
4092  len2;
4093  int cmp;
4094 
4095  len1 = VARSIZE_ANY_EXHDR(arg1);
4096  len2 = VARSIZE_ANY_EXHDR(arg2);
4097 
4098  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4099 
4100  PG_FREE_IF_COPY(arg1, 0);
4101  PG_FREE_IF_COPY(arg2, 1);
4102 
4103  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
4104 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:920
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555
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 4055 of file varlena.c.

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

4056 {
4057  Datum arg1 = PG_GETARG_DATUM(0);
4058  Datum arg2 = PG_GETARG_DATUM(1);
4059  bool result;
4060  Size len1,
4061  len2;
4062 
4063  /*
4064  * We can use a fast path for unequal lengths, which might save us from
4065  * having to detoast one or both values.
4066  */
4067  len1 = toast_raw_datum_size(arg1);
4068  len2 = toast_raw_datum_size(arg2);
4069  if (len1 != len2)
4070  result = true;
4071  else
4072  {
4073  bytea *barg1 = DatumGetByteaPP(arg1);
4074  bytea *barg2 = DatumGetByteaPP(arg2);
4075 
4076  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4077  len1 - VARHDRSZ) != 0);
4078 
4079  PG_FREE_IF_COPY(barg1, 0);
4080  PG_FREE_IF_COPY(barg2, 1);
4081  }
4082 
4083  PG_RETURN_BOOL(result);
4084 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define VARHDRSZ
Definition: c.h:561
#define DatumGetByteaPP(X)
Definition: fmgr.h:290
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:502
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
uintptr_t Datum
Definition: postgres.h:367
size_t Size
Definition: c.h:466
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 3170 of file varlena.c.

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

3171 {
3172  Datum str = PG_GETARG_DATUM(0);
3173 
3174  /* We need not detoast the input at all */
3176 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define VARHDRSZ
Definition: c.h:561
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:502
uintptr_t Datum
Definition: postgres.h:367

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 374 of file varlena.c.

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

Referenced by pg_mcv_list_out().

375 {
376  bytea *vlena = PG_GETARG_BYTEA_PP(0);
377  char *result;
378  char *rp;
379 
381  {
382  /* Print hex format */
383  rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
384  *rp++ = '\\';
385  *rp++ = 'x';
386  rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
387  }
388  else if (bytea_output == BYTEA_OUTPUT_ESCAPE)
389  {
390  /* Print traditional escaped format */
391  char *vp;
392  uint64 len;
393  int i;
394 
395  len = 1; /* empty string has 1 char */
396  vp = VARDATA_ANY(vlena);
397  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
398  {
399  if (*vp == '\\')
400  len += 2;
401  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
402  len += 4;
403  else
404  len++;
405  }
406 
407  /*
408  * In principle len can't overflow uint32 if the input fit in 1GB, but
409  * for safety let's check rather than relying on palloc's internal
410  * check.
411  */
412  if (len > MaxAllocSize)
413  ereport(ERROR,
414  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
415  errmsg_internal("result of bytea output conversion is too large")));
416  rp = result = (char *) palloc(len);
417 
418  vp = VARDATA_ANY(vlena);
419  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
420  {
421  if (*vp == '\\')
422  {
423  *rp++ = '\\';
424  *rp++ = '\\';
425  }
426  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
427  {
428  int val; /* holds unprintable chars */
429 
430  val = *vp;
431  rp[0] = '\\';
432  rp[3] = DIG(val & 07);
433  val >>= 3;
434  rp[2] = DIG(val & 07);
435  val >>= 3;
436  rp[1] = DIG(val & 03);
437  rp += 4;
438  }
439  else
440  *rp++ = *vp;
441  }
442  }
443  else
444  {
445  elog(ERROR, "unrecognized bytea_output setting: %d",
446  bytea_output);
447  rp = result = NULL; /* keep compiler quiet */
448  }
449  *rp = '\0';
450  PG_RETURN_CSTRING(result);
451 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
int bytea_output
Definition: varlena.c:42
uint64 hex_encode(const char *src, size_t len, char *dst)
Definition: encode.c:160
#define MaxAllocSize
Definition: memutils.h:40
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg_internal(const char *fmt,...)
Definition: elog.c:911
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:361
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:214
int i
Definition: c.h:555
long val
Definition: informix.c:664
#define DIG(VAL)
Definition: varlena.c:264

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 3335 of file varlena.c.

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

3336 {
3337  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3338  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3339  int sp = PG_GETARG_INT32(2); /* substring start position */
3340  int sl = PG_GETARG_INT32(3); /* substring length */
3341 
3342  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3343 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3358
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
Definition: c.h:555

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3346 of file varlena.c.

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

3347 {
3348  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3349  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3350  int sp = PG_GETARG_INT32(2); /* substring start position */
3351  int sl;
3352 
3353  sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
3354  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3355 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3358
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:307
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 3394 of file varlena.c.

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

3395 {
3396  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3397  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3398  int pos;
3399  int px,
3400  p;
3401  int len1,
3402  len2;
3403  char *p1,
3404  *p2;
3405 
3406  len1 = VARSIZE_ANY_EXHDR(t1);
3407  len2 = VARSIZE_ANY_EXHDR(t2);
3408 
3409  if (len2 <= 0)
3410  PG_RETURN_INT32(1); /* result for empty pattern */
3411 
3412  p1 = VARDATA_ANY(t1);
3413  p2 = VARDATA_ANY(t2);
3414 
3415  pos = 0;
3416  px = (len1 - len2);
3417  for (p = 0; p <= px; p++)
3418  {
3419  if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
3420  {
3421  pos = p + 1;
3422  break;
3423  };
3424  p1++;
3425  };
3426 
3427  PG_RETURN_INT32(pos);
3428 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
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:307
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

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

458 {
460  bytea *result;
461  int nbytes;
462 
463  nbytes = buf->len - buf->cursor;
464  result = (bytea *) palloc(nbytes + VARHDRSZ);
465  SET_VARSIZE(result, nbytes + VARHDRSZ);
466  pq_copymsgbytes(buf, VARDATA(result), nbytes);
467  PG_RETURN_BYTEA_P(result);
468 }
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:561
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
static char * buf
Definition: pg_test_fsync.c:67
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:530
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:555
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329

◆ byteasend()

Datum byteasend ( PG_FUNCTION_ARGS  )

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

477 {
478  bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
479 
480  PG_RETURN_BYTEA_P(vlena);
481 }
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:313
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
Definition: c.h:555

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 3537 of file varlena.c.

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

3538 {
3539  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3540  int64 n = PG_GETARG_INT64(1);
3541  int32 newBit = PG_GETARG_INT32(2);
3542  int len;
3543  int oldByte,
3544  newByte;
3545  int byteNo,
3546  bitNo;
3547 
3548  len = VARSIZE(res) - VARHDRSZ;
3549 
3550  if (n < 0 || n >= (int64) len * 8)
3551  ereport(ERROR,
3552  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3553  errmsg("index %lld out of valid range, 0..%lld",
3554  (long long) n, (long long) len * 8 - 1)));
3555 
3556  /* n/8 is now known < len, so safe to cast to int */
3557  byteNo = (int) (n / 8);
3558  bitNo = (int) (n % 8);
3559 
3560  /*
3561  * sanity check!
3562  */
3563  if (newBit != 0 && newBit != 1)
3564  ereport(ERROR,
3565  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3566  errmsg("new bit must be 0 or 1")));
3567 
3568  /*
3569  * Update the byte.
3570  */
3571  oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3572 
3573  if (newBit == 0)
3574  newByte = oldByte & (~(1 << bitNo));
3575  else
3576  newByte = oldByte | (1 << bitNo);
3577 
3578  ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3579 
3580  PG_RETURN_BYTEA_P(res);
3581 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:561
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:313
int errcode(int sqlerrcode)
Definition: elog.c:610
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
signed int int32
Definition: c.h:355
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555
#define PG_GETARG_INT64(n)
Definition: fmgr.h:282

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

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

3506 {
3507  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3508  int32 n = PG_GETARG_INT32(1);
3509  int32 newByte = PG_GETARG_INT32(2);
3510  int len;
3511 
3512  len = VARSIZE(res) - VARHDRSZ;
3513 
3514  if (n < 0 || n >= len)
3515  ereport(ERROR,
3516  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3517  errmsg("index %d out of valid range, 0..%d",
3518  n, len - 1)));
3519 
3520  /*
3521  * Now set the byte.
3522  */
3523  ((unsigned char *) VARDATA(res))[n] = newByte;
3524 
3525  PG_RETURN_BYTEA_P(res);
3526 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARSIZE(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:561
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:313
int errcode(int sqlerrcode)
Definition: elog.c:610
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:369
signed int int32
Definition: c.h:355
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555

◆ charlen_to_bytelen()

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

Definition at line 769 of file varlena.c.

References pg_database_encoding_max_length(), and pg_mblen().

Referenced by appendStringInfoRegexpSubstr(), and replace_text_regexp().

770 {
772  {
773  /* Optimization for single-byte encodings */
774  return n;
775  }
776  else
777  {
778  const char *s;
779 
780  for (s = p; n > 0; n--)
781  s += pg_mblen(s);
782 
783  return s - p;
784  }
785 }
int pg_mblen(const char *mbstr)
Definition: mbutils.c:907
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1436

◆ check_collation_set()

static void check_collation_set ( Oid  collid)
static

Definition at line 1465 of file varlena.c.

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

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

1466 {
1467  if (!OidIsValid(collid))
1468  {
1469  /*
1470  * This typically means that the parser could not resolve a conflict
1471  * of implicit collations, so report it that way.
1472  */
1473  ereport(ERROR,
1474  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1475  errmsg("could not determine which collation to use for string comparison"),
1476  errhint("Use the COLLATE clause to set the collation explicitly.")));
1477  }
1478 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
int errcode(int sqlerrcode)
Definition: elog.c:610
#define OidIsValid(objectId)
Definition: c.h:644
#define ERROR
Definition: elog.h:43
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ check_replace_text_has_escape_char()

static bool check_replace_text_has_escape_char ( const text replace_text)
static

Definition at line 4300 of file varlena.c.

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

Referenced by replace_text_regexp().

4301 {
4302  const char *p = VARDATA_ANY(replace_text);
4303  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4304 
4306  {
4307  for (; p < p_end; p++)
4308  {
4309  if (*p == '\\')
4310  return true;
4311  }
4312  }
4313  else
4314  {
4315  for (; p < p_end; p += pg_mblen(p))
4316  {
4317  if (*p == '\\')
4318  return true;
4319  }
4320  }
4321 
4322  return false;
4323 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int pg_mblen(const char *mbstr)
Definition: mbutils.c:907
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1436
#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 5248 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().

5250 {
5251  text *result;
5253  FmgrInfo *foutcache;
5254  bool first_arg = true;
5255  int i;
5256 
5257  /*
5258  * concat(VARIADIC some-array) is essentially equivalent to
5259  * array_to_text(), ie concat the array elements with the given separator.
5260  * So we just pass the case off to that code.
5261  */
5262  if (get_fn_expr_variadic(fcinfo->flinfo))
5263  {
5264  ArrayType *arr;
5265 
5266  /* Should have just the one argument */
5267  Assert(argidx == PG_NARGS() - 1);
5268 
5269  /* concat(VARIADIC NULL) is defined as NULL */
5270  if (PG_ARGISNULL(argidx))
5271  return NULL;
5272 
5273  /*
5274  * Non-null argument had better be an array. We assume that any call
5275  * context that could let get_fn_expr_variadic return true will have
5276  * checked that a VARIADIC-labeled parameter actually is an array. So
5277  * it should be okay to just Assert that it's an array rather than
5278  * doing a full-fledged error check.
5279  */
5281 
5282  /* OK, safe to fetch the array value */
5283  arr = PG_GETARG_ARRAYTYPE_P(argidx);
5284 
5285  /*
5286  * And serialize the array. We tell array_to_text to ignore null
5287  * elements, which matches the behavior of the loop below.
5288  */
5289  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5290  }
5291 
5292  /* Normal case without explicit VARIADIC marker */
5293  initStringInfo(&str);
5294 
5295  /* Get output function info, building it if first time through */
5296  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5297  if (foutcache == NULL)
5298  foutcache = build_concat_foutcache(fcinfo, argidx);
5299 
5300  for (i = argidx; i < PG_NARGS(); i++)
5301  {
5302  if (!PG_ARGISNULL(i))
5303  {
5305 
5306  /* add separator if appropriate */
5307  if (first_arg)
5308  first_arg = false;
5309  else
5310  appendStringInfoString(&str, sepstr);
5311 
5312  /* call the appropriate type output function, append the result */
5314  OutputFunctionCall(&foutcache[i], value));
5315  }
5316  }
5317 
5318  result = cstring_to_text_with_len(str.data, str.len);
5319  pfree(str.data);
5320 
5321  return result;
5322 }
Definition: fmgr.h:56
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1938
#define OidIsValid(objectId)
Definition: c.h:644
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1577
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:251
void pfree(void *pointer)
Definition: mcxt.c:1056
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1804
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4912
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo * flinfo
Definition: fmgr.h:87
static struct @143 value
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:738
#define PG_NARGS()
Definition: fmgr.h:203
void * fn_extra
Definition: fmgr.h:64
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2709
int i
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5210
Definition: c.h:555

◆ cstring_to_text()

text* cstring_to_text ( const char *  s)

Definition at line 172 of file varlena.c.

References cstring_to_text_with_len().

Referenced by array_dims(), ASN1_STRING_to_text(), booltext(), brin_page_type(), cash_words(), cidr_abbrev(), convert_charset(), cstring_to_xmltype(), current_query(), datetime_to_char_body(), dblink_build_sql_delete(), dblink_build_sql_insert(), dblink_build_sql_update(), dblink_cancel_query(), dblink_close(), dblink_connect(), dblink_disconnect(), dblink_error_message(), dblink_exec(), dblink_open(), dmetaphone(), dmetaphone_alt(), exec_assign_c_string(), executeDateTimeMethod(), filter_list_to_array(), format_type(), get_command_tag(), get_command_type(), get_jsonb_path_all(), get_scalar(), hash_page_type(), hstore_to_json(), hstore_to_json_loose(), inet_abbrev(), initcap(), json_in(), json_typeof(), jsonb_typeof(), JsonbValueAsText(), lower(), md5_bytea(), md5_text(), metaphone(), name_bpchar(), name_text(), network_host(), network_show(), oidvectortypes(), pg_collation_actual_version(), pg_collation_for(), pg_crypt(), pg_current_logfile(), pg_describe_object(), pg_export_snapshot(), pg_relation_filepath(), pg_size_pretty(), pg_size_pretty_numeric(), pg_stat_get_backend_activity(), pg_stat_get_backend_wait_event(), pg_stat_get_backend_wait_event_type(), pg_stat_get_slru(), pg_stats_ext_mcvlist_items(), pg_tablespace_location(), pg_walfile_name(), pg_xact_status(), pgsql_version(), pgxml_result_to_text(), quote_ident(), quote_ident_cstr(), quote_nullable(), sepgsql_getcon(), sepgsql_mcstrans_in(), sepgsql_mcstrans_out(), set_config_by_name(), show_all_file_settings(), show_config_by_name(), show_config_by_name_missing_ok(), ShowAllGUCConfig(), soundex(), SPI_sql_row_to_xmlelement(), split_text(), ssl_cipher(), ssl_version(), string_to_text(), text_substring(), textin(), timeofday(), to_hex32(), to_hex64(), tsquerytree(), unaccent_dict(), upper(), X509_NAME_to_text(), xml_encode_special_chars(), xml_in(), and xml_recv().

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

◆ cstring_to_text_with_len()

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

Definition at line 184 of file varlena.c.

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

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

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

◆ internal_text_pattern_compare()

static int internal_text_pattern_compare ( text arg1,
text arg2 
)
static

Definition at line 3045 of file varlena.c.

References Min, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

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

3046 {
3047  int result;
3048  int len1,
3049  len2;
3050 
3051  len1 = VARSIZE_ANY_EXHDR(arg1);
3052  len2 = VARSIZE_ANY_EXHDR(arg2);
3053 
3054  result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3055  if (result != 0)
3056  return result;
3057  else if (len1 < len2)
3058  return -1;
3059  else if (len1 > len2)
3060  return 1;
3061  else
3062  return 0;
3063 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define Min(x, y)
Definition: c.h:920
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5138 of file varlena.c.

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

Referenced by bytea_string_agg_transfn(), and string_agg_transfn().

5139 {
5140  StringInfo state;
5141  MemoryContext aggcontext;
5142  MemoryContext oldcontext;
5143 
5144  if (!AggCheckCallContext(fcinfo, &aggcontext))
5145  {
5146  /* cannot be called directly because of internal-type argument */
5147  elog(ERROR, "string_agg_transfn called in non-aggregate context");
5148  }
5149 
5150  /*
5151  * Create state in aggregate context. It'll stay there across subsequent
5152  * calls.
5153  */
5154  oldcontext = MemoryContextSwitchTo(aggcontext);
5155  state = makeStringInfo();
5156  MemoryContextSwitchTo(oldcontext);
5157 
5158  return state;
5159 }
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ERROR
Definition: elog.h:43
ts_parserstate state
Definition: tsquery.c:81
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4684
#define elog(elevel,...)
Definition: elog.h:214

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3611 of file varlena.c.

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

Referenced by nameiclike(), and nameicnlike().

3612 {
3613  Name s = PG_GETARG_NAME(0);
3614 
3616 }
Definition: c.h:609
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
text * cstring_to_text(const char *s)
Definition: varlena.c:172
#define NameStr(name)
Definition: c.h:615
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ nameeqtext()

Datum nameeqtext ( PG_FUNCTION_ARGS  )

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

2849 {
2850  Name arg1 = PG_GETARG_NAME(0);
2851  text *arg2 = PG_GETARG_TEXT_PP(1);
2852  size_t len1 = strlen(NameStr(*arg1));
2853  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2854  Oid collid = PG_GET_COLLATION();
2855  bool result;
2856 
2857  check_collation_set(collid);
2858 
2859  if (collid == C_COLLATION_OID)
2860  result = (len1 == len2 &&
2861  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2862  else
2863  result = (varstr_cmp(NameStr(*arg1), len1,
2864  VARDATA_ANY(arg2), len2,
2865  collid) == 0);
2866 
2867  PG_FREE_IF_COPY(arg2, 1);
2868 
2869  PG_RETURN_BOOL(result);
2870 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1494
static void check_collation_set(Oid collid)
Definition: varlena.c:1465
Definition: c.h:609
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:615
Definition: c.h:555
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ namefastcmp_c()

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

Definition at line 2211 of file varlena.c.

References DatumGetName, NAMEDATALEN, and NameStr.

Referenced by varstr_sortsupport().

2212 {
2213  Name arg1 = DatumGetName(x);
2214  Name arg2 = DatumGetName(y);
2215 
2216  return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2217 }
#define NAMEDATALEN
#define DatumGetName(X)
Definition: postgres.h:585
Definition: c.h:609
#define NameStr(name)
Definition: c.h:615

◆ namefastcmp_locale()

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

Definition at line 2254 of file varlena.c.

References DatumGetName, NameStr, and varstrfastcmp_locale().

Referenced by varstr_sortsupport().

2255 {
2256  Name arg1 = DatumGetName(x);
2257  Name arg2 = DatumGetName(y);
2258 
2259  return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)),
2260  NameStr(*arg2), strlen(NameStr(*arg2)),
2261  ssup);
2262 }
#define DatumGetName(X)
Definition: postgres.h:585
Definition: c.h:609
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2268
#define NameStr(name)
Definition: c.h:615

◆ namegetext()

Datum namegetext ( PG_FUNCTION_ARGS  )

Definition at line 3004 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

3005 {
3007 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2979
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2948

◆ namegttext()

Datum namegttext ( PG_FUNCTION_ARGS  )

Definition at line 2998 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2999 {
3001 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2979
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2948

◆ nameletext()

Datum nameletext ( PG_FUNCTION_ARGS  )

Definition at line 2992 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2993 {
2995 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2979
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2948

◆ namelttext()

Datum namelttext ( PG_FUNCTION_ARGS  )

Definition at line 2986 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

2987 {
2989 }
#define CmpCall(cmpfunc)
Definition: varlena.c:2979
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2948

◆ namenetext()

Datum namenetext ( PG_FUNCTION_ARGS  )

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

2899 {
2900  Name arg1 = PG_GETARG_NAME(0);
2901  text *arg2 = PG_GETARG_TEXT_PP(1);
2902  size_t len1 = strlen(NameStr(*arg1));
2903  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2904  Oid collid = PG_GET_COLLATION();
2905  bool result;
2906 
2907  check_collation_set(collid);
2908 
2909  if (collid == C_COLLATION_OID)
2910  result = !(len1 == len2 &&
2911  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2912  else
2913  result = !(varstr_cmp(NameStr(*arg1), len1,
2914  VARDATA_ANY(arg2), len2,
2915  collid) == 0);
2916 
2917  PG_FREE_IF_COPY(arg2, 1);
2918 
2919  PG_RETURN_BOOL(result);
2920 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1494
static void check_collation_set(Oid collid)
Definition: varlena.c:1465
Definition: c.h:609
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:615
Definition: c.h:555
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

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

5085 {
5087  int32 result;
5088  int typlen;
5089 
5090  /* On first call, get the input type's typlen, and save at *fn_extra */
5091  if (fcinfo->flinfo->fn_extra == NULL)
5092  {
5093  /* Lookup the datatype of the supplied argument */
5094  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5095 
5096  typlen = get_typlen(argtypeid);
5097  if (typlen == 0) /* should not happen */
5098  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5099 
5100  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5101  sizeof(int));
5102  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5103  }
5104  else
5105  typlen = *((int *) fcinfo->flinfo->fn_extra);
5106 
5107  if (typlen == -1)
5108  {
5109  /* varlena type, possibly toasted */
5110  result = toast_datum_size(value);
5111  }
5112  else if (typlen == -2)
5113  {
5114  /* cstring */
5115  result = strlen(DatumGetCString(value)) + 1;
5116  }
5117  else
5118  {
5119  /* ordinary fixed-width type */
5120  result = typlen;
5121  }
5122 
5123  PG_RETURN_INT32(result);
5124 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:355
Size toast_datum_size(Datum value)
Definition: detoast.c:558
#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:1804
uintptr_t Datum
Definition: postgres.h:367
static struct @143 value
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2085
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:214

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

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

4226 {
4227  text *src_text = PG_GETARG_TEXT_PP(0);
4228  text *from_sub_text = PG_GETARG_TEXT_PP(1);
4229  text *to_sub_text = PG_GETARG_TEXT_PP(2);
4230  int src_text_len;
4231  int from_sub_text_len;
4233  text *ret_text;
4234  int chunk_len;
4235  char *curr_ptr;
4236  char *start_ptr;
4238  bool found;
4239 
4240  src_text_len = VARSIZE_ANY_EXHDR(src_text);
4241  from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4242 
4243  /* Return unmodified source string if empty source or pattern */
4244  if (src_text_len < 1 || from_sub_text_len < 1)
4245  {
4246  PG_RETURN_TEXT_P(src_text);
4247  }
4248 
4249  text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4250 
4251  found = text_position_next(&state);
4252 
4253  /* When the from_sub_text is not found, there is nothing to do. */
4254  if (!found)
4255  {
4256  text_position_cleanup(&state);
4257  PG_RETURN_TEXT_P(src_text);
4258  }
4259  curr_ptr = text_position_get_match_ptr(&state);
4260  start_ptr = VARDATA_ANY(src_text);
4261 
4262  initStringInfo(&str);
4263 
4264  do
4265  {
4267 
4268  /* copy the data skipped over by last text_position_next() */
4269  chunk_len = curr_ptr - start_ptr;
4270  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4271 
4272  appendStringInfoText(&str, to_sub_text);
4273 
4274  start_ptr = curr_ptr + from_sub_text_len;
4275 
4276  found = text_position_next(&state);
4277  if (found)
4278  curr_ptr = text_position_get_match_ptr(&state);
4279  }
4280  while (found);
4281 
4282  /* copy trailing data */
4283  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4284  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4285 
4286  text_position_cleanup(&state);
4287 
4288  ret_text = cstring_to_text_with_len(str.data, str.len);
4289  pfree(str.data);
4290 
4291  PG_RETURN_TEXT_P(ret_text);
4292 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1297
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1430
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
void pfree(void *pointer)
Definition: mcxt.c:1056
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4211
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
ts_parserstate state
Definition: tsquery.c:81
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1459
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1168
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ replace_text_regexp()

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

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

4440 {
4441  text *ret_text;
4442  regex_t *re = (regex_t *) regexp;
4443  int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4446  pg_wchar *data;
4447  size_t data_len;
4448  int search_start;
4449  int data_pos;
4450  char *start_ptr;
4451  bool have_escape;
4452 
4453  initStringInfo(&buf);
4454 
4455  /* Convert data string to wide characters. */
4456  data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4457  data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4458 
4459  /* Check whether replace_text has escape char. */
4460  have_escape = check_replace_text_has_escape_char(replace_text);
4461 
4462  /* start_ptr points to the data_pos'th character of src_text */
4463  start_ptr = (char *) VARDATA_ANY(src_text);
4464  data_pos = 0;
4465 
4466  search_start = 0;
4467  while (search_start <= data_len)
4468  {
4469  int regexec_result;
4470 
4472 
4473  regexec_result = pg_regexec(re,
4474  data,
4475  data_len,
4476  search_start,
4477  NULL, /* no details */
4479  pmatch,
4480  0);
4481 
4482  if (regexec_result == REG_NOMATCH)
4483  break;
4484 
4485  if (regexec_result != REG_OKAY)
4486  {
4487  char errMsg[100];
4488 
4490  pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4491  ereport(ERROR,
4492  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4493  errmsg("regular expression failed: %s", errMsg)));
4494  }
4495 
4496  /*
4497  * Copy the text to the left of the match position. Note we are given
4498  * character not byte indexes.
4499  */
4500  if (pmatch[0].rm_so - data_pos > 0)
4501  {
4502  int chunk_len;
4503 
4504  chunk_len = charlen_to_bytelen(start_ptr,
4505  pmatch[0].rm_so - data_pos);
4506  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4507 
4508  /*
4509  * Advance start_ptr over that text, to avoid multiple rescans of
4510  * it if the replace_text contains multiple back-references.
4511  */
4512  start_ptr += chunk_len;
4513  data_pos = pmatch[0].rm_so;
4514  }
4515 
4516  /*
4517  * Copy the replace_text. Process back references when the
4518  * replace_text has escape characters.
4519  */
4520  if (have_escape)
4521  appendStringInfoRegexpSubstr(&buf, replace_text, pmatch,
4522  start_ptr, data_pos);
4523  else
4524  appendStringInfoText(&buf, replace_text);
4525 
4526  /* Advance start_ptr and data_pos over the matched text. */
4527  start_ptr += charlen_to_bytelen(start_ptr,
4528  pmatch[0].rm_eo - data_pos);
4529  data_pos = pmatch[0].rm_eo;
4530 
4531  /*
4532  * When global option is off, replace the first instance only.
4533  */
4534  if (!glob)
4535  break;
4536 
4537  /*
4538  * Advance search position. Normally we start the next search at the
4539  * end of the previous match; but if the match was of zero length, we
4540  * have to advance by one character, or we'd just find the same match
4541  * again.
4542  */
4543  search_start = data_pos;
4544  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4545  search_start++;
4546  }
4547 
4548  /*
4549  * Copy the text to the right of the last match.
4550  */
4551  if (data_pos < data_len)
4552  {
4553  int chunk_len;
4554 
4555  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4556  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4557  }
4558 
4559  ret_text = cstring_to_text_with_len(buf.data, buf.len);
4560  pfree(buf.data);
4561  pfree(data);
4562 
4563  return ret_text;
4564 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
regoff_t rm_so
Definition: regex.h:85
int errcode(int sqlerrcode)
Definition: elog.c:610
regoff_t rm_eo
Definition: regex.h:86
void pfree(void *pointer)
Definition: mcxt.c:1056
#define REG_OKAY
Definition: regex.h:137
#define ERROR
Definition: elog.h:43
static bool check_replace_text_has_escape_char(const text *replace_text)
Definition: varlena.c:4300
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:769
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4211
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define REGEXP_REPLACE_BACKREF_CNT
Definition: varlena.c:4427
#define VARSIZE_ANY(PTR)
Definition: postgres.h:335
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:870
#define ereport(elevel,...)
Definition: elog.h:144
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4333
int pg_regexec(regex_t *re, const chr *string, size_t len, size_t search_start, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags)
Definition: regexec.c:172
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define REG_NOMATCH
Definition: regex.h:138
Definition: c.h:555
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:99
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
Definition: regex.h:55

◆ rest_of_char_same()

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

Definition at line 5978 of file varlena.c.

Referenced by varstr_levenshtein().

5979 {
5980  while (len > 0)
5981  {
5982  len--;
5983  if (s1[len] != s2[len])
5984  return false;
5985  }
5986  return true;
5987 }
char * s1
char * s2

◆ split_text()

Datum split_text ( PG_FUNCTION_ARGS  )

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

4574 {
4575  text *inputstring = PG_GETARG_TEXT_PP(0);
4576  text *fldsep = PG_GETARG_TEXT_PP(1);
4577  int fldnum = PG_GETARG_INT32(2);
4578  int inputstring_len;
4579  int fldsep_len;
4581  char *start_ptr;
4582  char *end_ptr;
4583  text *result_text;
4584  bool found;
4585 
4586  /* field number is 1 based */
4587  if (fldnum < 1)
4588  ereport(ERROR,
4589  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4590  errmsg("field position must be greater than zero")));
4591 
4592  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4593  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4594 
4595  /* return empty string for empty input string */
4596  if (inputstring_len < 1)
4598 
4599  /* empty field separator */
4600  if (fldsep_len < 1)
4601  {
4602  text_position_cleanup(&state);
4603  /* if first field, return input string, else empty string */
4604  if (fldnum == 1)
4605  PG_RETURN_TEXT_P(inputstring);
4606  else
4608  }
4609 
4610  text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4611 
4612  /* identify bounds of first field */
4613  start_ptr = VARDATA_ANY(inputstring);
4614  found = text_position_next(&state);
4615 
4616  /* special case if fldsep not found at all */
4617  if (!found)
4618  {
4619  text_position_cleanup(&state);
4620  /* if field 1 requested, return input string, else empty string */
4621  if (fldnum == 1)
4622  PG_RETURN_TEXT_P(inputstring);
4623  else
4625  }
4626  end_ptr = text_position_get_match_ptr(&state);
4627 
4628  while (found && --fldnum > 0)
4629  {
4630  /* identify bounds of next field */
4631  start_ptr = end_ptr + fldsep_len;
4632  found = text_position_next(&state);
4633  if (found)
4634  end_ptr = text_position_get_match_ptr(&state);
4635  }
4636 
4637  text_position_cleanup(&state);
4638 
4639  if (fldnum > 0)
4640  {
4641  /* N'th field separator not found */
4642  /* if last field requested, return it, else empty string */
4643  if (fldnum == 1)
4644  {
4645  int last_len = start_ptr - VARDATA_ANY(inputstring);
4646 
4647  result_text = cstring_to_text_with_len(start_ptr,
4648  inputstring_len - last_len);
4649  }
4650  else
4651  result_text = cstring_to_text("");
4652  }
4653  else
4654  {
4655  /* non-last field requested */
4656  result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4657  }
4658 
4659  PG_RETURN_TEXT_P(result_text);
4660 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1297
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1430
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#define ERROR
Definition: elog.h:43
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
ts_parserstate state
Definition: tsquery.c:81
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1459
#define ereport(elevel,...)
Definition: elog.h:144
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
text * cstring_to_text(const char *s)
Definition: varlena.c:172
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1168
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555

◆ SplitDirectoriesString()

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

Definition at line 3813 of file varlena.c.

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

Referenced by load_libraries(), and PostmasterMain().

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

◆ SplitGUCList()

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

Definition at line 3934 of file varlena.c.

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

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

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

◆ SplitIdentifierString()

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

Definition at line 3686 of file varlena.c.

References Assert, downcase_truncate_identifier(), lappend(), 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_output_parameters(), parse_publication_options(), plpgsql_extra_checks_check_hook(), PrepareTempTablespaces(), recomputeNamespacePath(), stringToQualifiedNameList(), and textToQualifiedNameList().

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

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

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

5189 {
5190  StringInfo state;
5191 
5192  /* cannot be called directly because of internal-type argument */
5193  Assert(AggCheckCallContext(fcinfo, NULL));
5194 
5195  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5196 
5197  if (state != NULL)
5199  else
5200  PG_RETURN_NULL();
5201 }
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
ts_parserstate state
Definition: tsquery.c:81
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:738
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4684
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 5162 of file varlena.c.

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

5163 {
5164  StringInfo state;
5165 
5166  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5167 
5168  /* Append the value unless null. */
5169  if (!PG_ARGISNULL(1))
5170  {
5171  /* On the first time through, we ignore the delimiter. */
5172  if (state == NULL)
5173  state = makeStringAggState(fcinfo);
5174  else if (!PG_ARGISNULL(2))
5175  appendStringInfoText(state, PG_GETARG_TEXT_PP(2)); /* delimiter */
5176 
5177  appendStringInfoText(state, PG_GETARG_TEXT_PP(1)); /* value */
5178  }
5179 
5180  /*
5181  * The transition type for string_agg() is declared to be "internal",
5182  * which is a pass-by-value type the same size as a pointer.
5183  */
5184  PG_RETURN_POINTER(state);
5185 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:360
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4211
ts_parserstate state
Definition: tsquery.c:81
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5138

◆ text_catenate()

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

Definition at line 728 of file varlena.c.

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

Referenced by text_overlay(), and textcat().

729 {
730  text *result;
731  int len1,
732  len2,
733  len;
734  char *ptr;
735 
736  len1 = VARSIZE_ANY_EXHDR(t1);
737  len2 = VARSIZE_ANY_EXHDR(t2);
738 
739  /* paranoia ... probably should throw error instead? */
740  if (len1 < 0)
741  len1 = 0;
742  if (len2 < 0)
743  len2 = 0;
744 
745  len = len1 + len2 + VARHDRSZ;
746  result = (text *) palloc(len);
747 
748  /* Set size of result string... */
749  SET_VARSIZE(result, len);
750 
751  /* Fill data field of result string... */
752  ptr = VARDATA(result);
753  if (len1 > 0)
754  memcpy(ptr, VARDATA_ANY(t1), len1);
755  if (len2 > 0)
756  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
757 
758  return result;
759 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARDATA(PTR)
Definition: postgres.h:302
#define VARHDRSZ
Definition: c.h:561
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
Definition: c.h:555
#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 1710 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().

1711 {
1712  char *a1p,
1713  *a2p;
1714  int len1,
1715  len2;
1716 
1717  a1p = VARDATA_ANY(arg1);
1718  a2p = VARDATA_ANY(arg2);
1719 
1720  len1 = VARSIZE_ANY_EXHDR(arg1);
1721  len2 = VARSIZE_ANY_EXHDR(arg2);
1722 
1723  return varstr_cmp(a1p, len1, a2p, len2, collid);
1724 }
#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:1494
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 5328 of file varlena.c.

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

5329 {
5330  text *result;
5331 
5332  result = concat_internal("", 0, fcinfo);
5333  if (result == NULL)
5334  PG_RETURN_NULL();
5335  PG_RETURN_TEXT_P(result);
5336 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5248
Definition: c.h:555
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5343 of file varlena.c.

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

5344 {
5345  char *sep;
5346  text *result;
5347 
5348  /* return NULL when separator is NULL */
5349  if (PG_ARGISNULL(0))
5350  PG_RETURN_NULL();
5352 
5353  result = concat_internal(sep, 1, fcinfo);
5354  if (result == NULL)
5355  PG_RETURN_NULL();
5356  PG_RETURN_TEXT_P(result);
5357 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5248
char * text_to_cstring(const text *t)
Definition: varlena.c:205
Definition: c.h:555
#define PG_RETURN_NULL()
Definition: fmgr.h:344

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

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

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

◆ text_format_append_string()

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

Definition at line 5916 of file varlena.c.

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

Referenced by text_format_string_conversion().

5918 {
5919  bool align_to_left = false;
5920  int len;
5921 
5922  /* fast path for typical easy case */
5923  if (width == 0)
5924  {
5926  return;
5927  }
5928 
5929  if (width < 0)
5930  {
5931  /* Negative width: implicit '-' flag, then take absolute value */
5932  align_to_left = true;
5933  /* -INT_MIN is undefined */
5934  if (width <= INT_MIN)
5935  ereport(ERROR,
5936  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5937  errmsg("number is out of range")));
5938  width = -width;
5939  }
5940  else if (flags & TEXT_FORMAT_FLAG_MINUS)
5941  align_to_left = true;
5942 
5943  len = pg_mbstrlen(str);
5944  if (align_to_left)
5945  {
5946  /* left justify */
5948  if (len < width)
5949  appendStringInfoSpaces(buf, width - len);
5950  }
5951  else
5952  {
5953  /* right justify */
5954  if (len < width)
5955  appendStringInfoSpaces(buf, width - len);
5957  }
5958 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:206
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:921
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5449

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 5968 of file varlena.c.

References text_format().

5969 {
5970  return text_format(fcinfo);
5971 }
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5464

◆ text_format_parse_digits()

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

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

5742 {
5743  bool found = false;
5744  const char *cp = *ptr;
5745  int val = 0;
5746 
5747  while (*cp >= '0' && *cp <= '9')
5748  {
5749  int8 digit = (*cp - '0');
5750 
5751  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5752  unlikely(pg_add_s32_overflow(val, digit, &val)))
5753  ereport(ERROR,
5754  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5755  errmsg("number is out of range")));
5756  ADVANCE_PARSE_POINTER(cp, end_ptr);
5757  found = true;
5758  }
5759 
5760  *ptr = cp;
5761  *value = val;
5762 
5763  return found;
5764 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5451
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
signed char int8
Definition: c.h:353
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:144
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define unlikely(x)
Definition: c.h:206
long val
Definition: informix.c:664

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

5793 {
5794  const char *cp = start_ptr;
5795  int n;
5796 
5797  /* set defaults for output parameters */
5798  *argpos = -1;
5799  *widthpos = -1;
5800  *flags = 0;
5801  *width = 0;
5802 
5803  /* try to identify first number */
5804  if (text_format_parse_digits(&cp, end_ptr, &n))
5805  {
5806  if (*cp != '$')
5807  {
5808  /* Must be just a width and a type, so we're done */
5809  *width = n;
5810  return cp;
5811  }
5812  /* The number was argument position */
5813  *argpos = n;
5814  /* Explicit 0 for argument index is immediately refused */
5815  if (n == 0)
5816  ereport(ERROR,
5817  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5818  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5819  ADVANCE_PARSE_POINTER(cp, end_ptr);
5820  }
5821 
5822  /* Handle flags (only minus is supported now) */
5823  while (*cp == '-')
5824  {
5825  *flags |= TEXT_FORMAT_FLAG_MINUS;
5826  ADVANCE_PARSE_POINTER(cp, end_ptr);
5827  }
5828 
5829  if (*cp == '*')
5830  {
5831  /* Handle indirect width */
5832  ADVANCE_PARSE_POINTER(cp, end_ptr);
5833  if (text_format_parse_digits(&cp, end_ptr, &n))
5834  {
5835  /* number in this position must be closed by $ */
5836  if (*cp != '$')
5837  ereport(ERROR,
5838  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5839  errmsg("width argument position must be ended by \"$\"")));
5840  /* The number was width argument position */
5841  *widthpos = n;
5842  /* Explicit 0 for argument index is immediately refused */
5843  if (n == 0)
5844  ereport(ERROR,
5845  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5846  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5847  ADVANCE_PARSE_POINTER(cp, end_ptr);
5848  }
5849  else
5850  *widthpos = 0; /* width's argument position is unspecified */
5851  }
5852  else
5853  {
5854  /* Check for direct width specification */
5855  if (text_format_parse_digits(&cp, end_ptr, &n))
5856  *width = n;
5857  }
5858 
5859  /* cp should now be pointing at type character */
5860  return cp;
5861 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5451
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:5741
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5449

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

5871 {
5872  char *str;
5873 
5874  /* Handle NULL arguments before trying to stringify the value. */
5875  if (isNull)
5876  {
5877  if (conversion == 's')
5878  text_format_append_string(buf, "", flags, width);
5879  else if (conversion == 'L')
5880  text_format_append_string(buf, "NULL", flags, width);
5881  else if (conversion == 'I')
5882  ereport(ERROR,
5883  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5884  errmsg("null values cannot be formatted as an SQL identifier")));
5885  return;
5886  }
5887 
5888  /* Stringify. */
5889  str = OutputFunctionCall(typOutputInfo, value);
5890 
5891  /* Escape. */
5892  if (conversion == 'I')
5893  {
5894  /* quote_identifier may or may not allocate a new string. */
5895  text_format_append_string(buf, quote_identifier(str), flags, width);
5896  }
5897  else if (conversion == 'L')
5898  {
5899  char *qstr = quote_literal_cstr(str);
5900 
5901  text_format_append_string(buf, qstr, flags, width);
5902  /* quote_literal_cstr() always allocates a new string */
5903  pfree(qstr);
5904  }
5905  else
5906  text_format_append_string(buf, str, flags, width);
5907 
5908  /* Cleanup. */
5909  pfree(str);
5910 }
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:102
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10737
int errcode(int sqlerrcode)
Definition: elog.c:610
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:5916
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1577
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

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

1883 {
1884  text *arg1 = PG_GETARG_TEXT_PP(0);
1885  text *arg2 = PG_GETARG_TEXT_PP(1);
1886  bool result;
1887 
1888  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1889 
1890  PG_FREE_IF_COPY(arg1, 0);
1891  PG_FREE_IF_COPY(arg2, 1);
1892 
1893  PG_RETURN_BOOL(result);
1894 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1710
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

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

1868 {
1869  text *arg1 = PG_GETARG_TEXT_PP(0);
1870  text *arg2 = PG_GETARG_TEXT_PP(1);
1871  bool result;
1872 
1873  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1874 
1875  PG_FREE_IF_COPY(arg1, 0);
1876  PG_FREE_IF_COPY(arg2, 1);
1877 
1878  PG_RETURN_BOOL(result);
1879 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1710
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_isequal()

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

Definition at line 4666 of file varlena.c.

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

Referenced by text_to_array_internal().

4667 {
4669  collid,
4670  PointerGetDatum(txt1),
4671  PointerGetDatum(txt2)));
4672 }
#define PointerGetDatum(X)
Definition: postgres.h:556
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1735
#define DatumGetBool(X)
Definition: postgres.h:393
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:815

◆ text_larger()

Datum text_larger ( PG_FUNCTION_ARGS  )

Definition at line 2819 of file varlena.c.

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

2820 {
2821  text *arg1 = PG_GETARG_TEXT_PP(0);
2822  text *arg2 = PG_GETARG_TEXT_PP(1);
2823  text *result;
2824 
2825  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2826 
2827  PG_RETURN_TEXT_P(result);
2828 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1710
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
Definition: c.h:555

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

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

1853 {
1854  text *arg1 = PG_GETARG_TEXT_PP(0);
1855  text *arg2 = PG_GETARG_TEXT_PP(1);
1856  bool result;
1857 
1858  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1859 
1860  PG_FREE_IF_COPY(arg1, 0);
1861  PG_FREE_IF_COPY(arg2, 1);
1862 
1863  PG_RETURN_BOOL(result);
1864 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1710
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

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

5365 {
5366  int n = PG_GETARG_INT32(1);
5367 
5368  if (n < 0)
5369  {
5370  text *str = PG_GETARG_TEXT_PP(0);
5371  const char *p = VARDATA_ANY(str);
5372  int len = VARSIZE_ANY_EXHDR(str);
5373  int rlen;
5374 
5375  n = pg_mbstrlen_with_len(p, len) + n;
5376  rlen = pg_mbcharcliplen(p, len, n);
5378  }
5379  else
5381 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1009
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:941
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:848
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:370
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555

◆ text_length()

static int32 text_length ( Datum  str)
static

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

675 {
676  /* fastpath when max encoding length is one */
679  else
680  {
681  text *t = DatumGetTextPP(str);
682 
684  VARSIZE_ANY_EXHDR(t)));
685  }
686 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define VARHDRSZ
Definition: c.h:561
#define DatumGetTextPP(X)
Definition: fmgr.h:291
#define PG_RETURN_INT32(x)
Definition: fmgr.h:353
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:941
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:502
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1436
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
Definition: c.h:555

◆ text_lt()

Datum text_lt ( PG_FUNCTION_ARGS  )

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

1838 {
1839  text *arg1 = PG_GETARG_TEXT_PP(0);
1840  text *arg2 = PG_GETARG_TEXT_PP(1);
1841  bool result;
1842 
1843  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
1844 
1845  PG_FREE_IF_COPY(arg1, 0);
1846  PG_FREE_IF_COPY(arg2, 1);
1847 
1848  PG_RETURN_BOOL(result);
1849 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1710
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_name()

Datum text_name ( PG_FUNCTION_ARGS  )

Definition at line 3588 of file varlena.c.

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

3589 {
3590  text *s = PG_GETARG_TEXT_PP(0);
3591  Name result;
3592  int len;
3593 
3594  len = VARSIZE_ANY_EXHDR(s);
3595 
3596  /* Truncate oversize input */
3597  if (len >= NAMEDATALEN)
3598  len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1);
3599 
3600  /* We use palloc0 here to ensure result is zero-padded */
3601  result = (Name) palloc0(NAMEDATALEN);
3602  memcpy(NameStr(*result), VARDATA_ANY(s), len);
3603 
3604  PG_RETURN_NAME(result);
3605 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
#define NAMEDATALEN
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:967
Definition: c.h:609
void * palloc0(Size size)
Definition: mcxt.c:980
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
#define NameStr(name)
Definition: c.h:615
Definition: c.h:555
NameData * Name
Definition: c.h:613
#define PG_RETURN_NAME(x)
Definition: fmgr.h:362

◆ text_overlay()

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

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

1069 {
1070  text *result;
1071  text *s1;
1072  text *s2;
1073  int sp_pl_sl;
1074 
1075  /*
1076  * Check for possible integer-overflow cases. For negative sp, throw a
1077  * "substring length" error because that's what should be expected
1078  * according to the spec's definition of OVERLAY().
1079  */
1080  if (sp <= 0)
1081  ereport(ERROR,
1082  (errcode(ERRCODE_SUBSTRING_ERROR),
1083  errmsg("negative substring length not allowed")));
1084  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
1085  ereport(ERROR,
1086  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1087  errmsg("integer out of range")));
1088 
1089  s1 = text_substring(PointerGetDatum(t1), 1, sp - 1, false);
1090  s2 = text_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
1091  result = text_catenate(s1, t2);
1092  result = text_catenate(result, s2);
1093 
1094  return result;
1095 }
#define PointerGetDatum(X)
Definition: postgres.h:556
int errcode(int sqlerrcode)
Definition: elog.c:610
#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:848
static text * text_catenate(text *t1, text *t2)
Definition: varlena.c:728
char * s2
#define ereport(elevel,...)
Definition: elog.h:144
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:824
Definition: c.h:555

◆ text_pattern_ge()

Datum text_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 3099 of file varlena.c.

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

3100 {
3101  text *arg1 = PG_GETARG_TEXT_PP(0);
3102  text *arg2 = PG_GETARG_TEXT_PP(1);
3103  int result;
3104 
3105  result = internal_text_pattern_compare(arg1, arg2);
3106 
3107  PG_FREE_IF_COPY(arg1, 0);
3108  PG_FREE_IF_COPY(arg2, 1);
3109 
3110  PG_RETURN_BOOL(result >= 0);
3111 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3045
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_pattern_gt()

Datum text_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 3115 of file varlena.c.

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

3116 {
3117  text *arg1 = PG_GETARG_TEXT_PP(0);
3118  text *arg2 = PG_GETARG_TEXT_PP(1);
3119  int result;
3120 
3121  result = internal_text_pattern_compare(arg1, arg2);
3122 
3123  PG_FREE_IF_COPY(arg1, 0);
3124  PG_FREE_IF_COPY(arg2, 1);
3125 
3126  PG_RETURN_BOOL(result > 0);
3127 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3045
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_pattern_le()

Datum text_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 3083 of file varlena.c.

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

3084 {
3085  text *arg1 = PG_GETARG_TEXT_PP(0);
3086  text *arg2 = PG_GETARG_TEXT_PP(1);
3087  int result;
3088 
3089  result = internal_text_pattern_compare(arg1, arg2);
3090 
3091  PG_FREE_IF_COPY(arg1, 0);
3092  PG_FREE_IF_COPY(arg2, 1);
3093 
3094  PG_RETURN_BOOL(result <= 0);
3095 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3045
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_pattern_lt()

Datum text_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 3067 of file varlena.c.

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

3068 {
3069  text *arg1 = PG_GETARG_TEXT_PP(0);
3070  text *arg2 = PG_GETARG_TEXT_PP(1);
3071  int result;
3072 
3073  result = internal_text_pattern_compare(arg1, arg2);
3074 
3075  PG_FREE_IF_COPY(arg1, 0);
3076  PG_FREE_IF_COPY(arg2, 1);
3077 
3078  PG_RETURN_BOOL(result < 0);
3079 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:308
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3045
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:358
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:555

◆ text_position()

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

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

1129 {
1131  int result;
1132 
1133  /* Empty needle always matches at position 1 */
1134  if (VARSIZE_ANY_EXHDR(t2) < 1)
1135  return 1;
1136 
1137  /* Otherwise, can't match if haystack is shorter than needle */
1138  if (VARSIZE_ANY_EXHDR(t1) < VARSIZE_ANY_EXHDR(t2))
1139  return 0;
1140 
1141  text_position_setup(t1, t2, collid, &state);
1142  if (!text_position_next(&state))
1143  result = 0;
1144  else
1145  result = text_position_get_match_pos(&state);
1146  text_position_cleanup(&state);
1147  return result;
1148 }
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1297
static int text_position_get_match_pos(TextPositionState *state)
Definition: varlena.c:1441
ts_parserstate state
Definition: tsquery.c:81
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1459
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1168
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341

◆ text_position_cleanup()

static void text_position_cleanup ( TextPositionState state)
static

Definition at line 1459 of file varlena.c.

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

1460 {
1461  /* no cleanup needed */
1462 }

◆ text_position_get_match_pos()

static int text_position_get_match_pos ( TextPositionState state)
static

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

1442 {
1443  if (!state->is_multibyte)
1444  return state->last_match - state->str1 + 1;
1445  else
1446  {
1447  /* Convert the byte position to char position. */
1448  while (state->refpoint < state->last_match)
1449  {
1450  state->refpoint += pg_mblen(state->refpoint);
1451  state->refpos++;
1452  }
1453  Assert(state->refpoint == state->last_match);
1454  return state->refpos + 1;
1455  }
1456 }
char * refpoint
Definition: varlena.c:72
char * last_match
Definition: varlena.c:64
bool is_multibyte
Definition: varlena.c:52
#define Assert(condition)
Definition: c.h:738
int pg_mblen(const char *mbstr)
Definition: mbutils.c:907

◆ text_position_get_match_ptr()

static char * text_position_get_match_ptr ( TextPositionState state)
static

Definition at line 1430 of file varlena.c.

References TextPositionState::last_match.

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

1431 {
1432  return state->last_match;
1433 }
char * last_match
Definition: varlena.c:64

◆ text_position_next()

static bool text_position_next ( TextPositionState state)
static

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

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

◆ text_position_next_internal()

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

Definition at line 1361 of file varlena.c.

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

Referenced by text_position_next().

1362 {
1363  int haystack_len = state->len1;
1364  int needle_len = state->len2;
1365  int skiptablemask = state->skiptablemask;
1366  const char *haystack = state->str1;
1367  const char *needle = state->str2;
1368  const char *haystack_end = &haystack[haystack_len];
1369  const char *hptr;
1370 
1371  Assert(start_ptr >= haystack && start_ptr <= haystack_end);
1372 
1373  if (needle_len == 1)
1374  {
1375  /* No point in using B-M-H for a one-character needle */
1376  char nchar = *needle;
1377 
1378  hptr = start_ptr;
1379  while (hptr < haystack_end)
1380  {
1381  if (*hptr == nchar)
1382  return (char *) hptr;
1383  hptr++;
1384  }
1385  }
1386  else
1387  {
1388  const char *needle_last = &needle[needle_len - 1];
1389 
1390  /* Start at startpos plus the length of the needle */
1391  hptr = start_ptr + needle_len - 1;
1392  while (hptr < haystack_end)
1393  {
1394  /* Match the needle scanning *backward* */
1395  const char *nptr;
1396  const char *p;
1397 
1398  nptr = needle_last;
1399  p = hptr;
1400  while (*nptr == *p)
1401  {
1402  /* Matched it all? If so, return 1-based position */
1403  if (nptr == needle)
1404  return (char *) p;
1405  nptr--, p--;
1406  }
1407 
1408  /*
1409  * No match, so use the haystack char at hptr to decide how far to
1410  * advance. If the needle had any occurrence of that character
1411  * (or more precisely, one sharing the same skiptable entry)
1