PostgreSQL Source Code  git master
varlena.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <limits.h>
#include "access/hash.h"
#include "access/tuptoaster.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "common/int.h"
#include "common/md5.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 PG_STR_GET_BYTEA(str_)   DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
 
#define REGEXP_REPLACE_BACKREF_CNT   10
 
#define HEXBASE   16
 
#define MD5_HASH_LEN   32
 
#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 varstrfastcmp_locale (Datum x, Datum y, 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)
 
static void text_position_setup (text *t1, text *t2, TextPositionState *state)
 
static int text_position_next (int start_pos, TextPositionState *state)
 
static void text_position_cleanup (TextPositionState *state)
 
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 bttextcmp (PG_FUNCTION_ARGS)
 
Datum bttextsortsupport (PG_FUNCTION_ARGS)
 
void varstr_sortsupport (SortSupport ssup, Oid collid, bool bpchar)
 
Datum text_larger (PG_FUNCTION_ARGS)
 
Datum text_smaller (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)
 
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)
 
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 md5_text (PG_FUNCTION_ARGS)
 
Datum md5_bytea (PG_FUNCTION_ARGS)
 
Datum pg_column_size (PG_FUNCTION_ARGS)
 
Datum string_agg_transfn (PG_FUNCTION_ARGS)
 
Datum string_agg_finalfn (PG_FUNCTION_ARGS)
 
static FmgrInfobuild_concat_foutcache (FunctionCallInfo fcinfo, int argidx)
 
static textconcat_internal (const char *sepstr, int argidx, FunctionCallInfo fcinfo)
 
Datum text_concat (PG_FUNCTION_ARGS)
 
Datum text_concat_ws (PG_FUNCTION_ARGS)
 
Datum text_left (PG_FUNCTION_ARGS)
 
Datum text_right (PG_FUNCTION_ARGS)
 
Datum text_reverse (PG_FUNCTION_ARGS)
 
Datum text_format (PG_FUNCTION_ARGS)
 
Datum text_format_nv (PG_FUNCTION_ARGS)
 
static bool rest_of_char_same (const char *s1, const char *s2, int len)
 

Variables

int bytea_output = BYTEA_OUTPUT_HEX
 

Macro Definition Documentation

◆ ADVANCE_PARSE_POINTER

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

Definition at line 4983 of file varlena.c.

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

◆ DatumGetUnknownP

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

Definition at line 86 of file varlena.c.

◆ DatumGetUnknownPCopy

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

Definition at line 87 of file varlena.c.

◆ DatumGetVarStringP

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

Definition at line 92 of file varlena.c.

◆ DatumGetVarStringPP

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

Definition at line 93 of file varlena.c.

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

◆ DIG

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

Definition at line 242 of file varlena.c.

Referenced by byteaout().

◆ HEXBASE

#define HEXBASE   16

Definition at line 4518 of file varlena.c.

Referenced by to_hex32(), and to_hex64().

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

Definition at line 5523 of file varlena.c.

◆ MD5_HASH_LEN

#define MD5_HASH_LEN   32

Definition at line 4572 of file varlena.c.

Referenced by md5_bytea(), and md5_text().

◆ PG_GETARG_UNKNOWN_P

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

Definition at line 88 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P_COPY

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

Definition at line 89 of file varlena.c.

◆ PG_RETURN_UNKNOWN_P

#define PG_RETURN_UNKNOWN_P (   x)    PG_RETURN_POINTER(x)

Definition at line 90 of file varlena.c.

◆ PG_STR_GET_BYTEA

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

Definition at line 2813 of file varlena.c.

Referenced by bytea_substring().

◆ REGEXP_REPLACE_BACKREF_CNT

#define REGEXP_REPLACE_BACKREF_CNT   10

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

Referenced by text_format_append_string(), and text_format_parse_format().

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 84 of file varlena.c.

Referenced by varstr_cmp(), and varstr_sortsupport().

◆ VAL

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

Definition at line 241 of file varlena.c.

Referenced by byteain().

Typedef Documentation

◆ unknown

Definition at line 44 of file varlena.c.

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

3809 {
3810  const char *p = VARDATA_ANY(replace_text);
3811  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
3812  int eml = pg_database_encoding_max_length();
3813 
3814  for (;;)
3815  {
3816  const char *chunk_start = p;
3817  int so;
3818  int eo;
3819 
3820  /* Find next escape char. */
3821  if (eml == 1)
3822  {
3823  for (; p < p_end && *p != '\\'; p++)
3824  /* nothing */ ;
3825  }
3826  else
3827  {
3828  for (; p < p_end && *p != '\\'; p += pg_mblen(p))
3829  /* nothing */ ;
3830  }
3831 
3832  /* Copy the text we just scanned over, if any. */
3833  if (p > chunk_start)
3834  appendBinaryStringInfo(str, chunk_start, p - chunk_start);
3835 
3836  /* Done if at end of string, else advance over escape char. */
3837  if (p >= p_end)
3838  break;
3839  p++;
3840 
3841  if (p >= p_end)
3842  {
3843  /* Escape at very end of input. Treat same as unexpected char */
3844  appendStringInfoChar(str, '\\');
3845  break;
3846  }
3847 
3848  if (*p >= '1' && *p <= '9')
3849  {
3850  /* Use the back reference of regexp. */
3851  int idx = *p - '0';
3852 
3853  so = pmatch[idx].rm_so;
3854  eo = pmatch[idx].rm_eo;
3855  p++;
3856  }
3857  else if (*p == '&')
3858  {
3859  /* Use the entire matched string. */
3860  so = pmatch[0].rm_so;
3861  eo = pmatch[0].rm_eo;
3862  p++;
3863  }
3864  else if (*p == '\\')
3865  {
3866  /* \\ means transfer one \ to output. */
3867  appendStringInfoChar(str, '\\');
3868  p++;
3869  continue;
3870  }
3871  else
3872  {
3873  /*
3874  * If escape char is not followed by any expected char, just treat
3875  * it as ordinary data to copy. (XXX would it be better to throw
3876  * an error?)
3877  */
3878  appendStringInfoChar(str, '\\');
3879  continue;
3880  }
3881 
3882  if (so != -1 && eo != -1)
3883  {
3884  /*
3885  * Copy the text that is back reference of regexp. Note so and eo
3886  * are counted in characters not bytes.
3887  */
3888  char *chunk_start;
3889  int chunk_len;
3890 
3891  Assert(so >= data_pos);
3892  chunk_start = start_ptr;
3893  chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
3894  chunk_len = charlen_to_bytelen(chunk_start, eo - so);
3895  appendBinaryStringInfo(str, chunk_start, chunk_len);
3896  }
3897  }
3898 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
regoff_t rm_so
Definition: regex.h:85
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:264
regoff_t rm_eo
Definition: regex.h:86
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:736
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
#define Assert(condition)
Definition: c.h:680
int pg_mblen(const char *mbstr)
Definition: mbutils.c:760
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208

◆ appendStringInfoText()

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

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

3677 {
3679 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

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

4360 {
4362  char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4363 
4364  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4365 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4401
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
char * text_to_cstring(const text *t)
Definition: varlena.c:183

◆ 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 4401 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, FunctionCallInfoData::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, 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().

4403 {
4404  text *result;
4405  int nitems,
4406  *dims,
4407  ndims;
4408  Oid element_type;
4409  int typlen;
4410  bool typbyval;
4411  char typalign;
4413  bool printed = false;
4414  char *p;
4415  bits8 *bitmap;
4416  int bitmask;
4417  int i;
4418  ArrayMetaState *my_extra;
4419 
4420  ndims = ARR_NDIM(v);
4421  dims = ARR_DIMS(v);
4422  nitems = ArrayGetNItems(ndims, dims);
4423 
4424  /* if there are no elements, return an empty string */
4425  if (nitems == 0)
4426  return cstring_to_text_with_len("", 0);
4427 
4428  element_type = ARR_ELEMTYPE(v);
4429  initStringInfo(&buf);
4430 
4431  /*
4432  * We arrange to look up info about element type, including its output
4433  * conversion proc, only once per series of calls, assuming the element
4434  * type doesn't change underneath us.
4435  */
4436  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4437  if (my_extra == NULL)
4438  {
4439  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4440  sizeof(ArrayMetaState));
4441  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
4442  my_extra->element_type = ~element_type;
4443  }
4444 
4445  if (my_extra->element_type != element_type)
4446  {
4447  /*
4448  * Get info about element type, including its output conversion proc
4449  */
4450  get_type_io_data(element_type, IOFunc_output,
4451  &my_extra->typlen, &my_extra->typbyval,
4452  &my_extra->typalign, &my_extra->typdelim,
4453  &my_extra->typioparam, &my_extra->typiofunc);
4454  fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
4455  fcinfo->flinfo->fn_mcxt);
4456  my_extra->element_type = element_type;
4457  }
4458  typlen = my_extra->typlen;
4459  typbyval = my_extra->typbyval;
4460  typalign = my_extra->typalign;
4461 
4462  p = ARR_DATA_PTR(v);
4463  bitmap = ARR_NULLBITMAP(v);
4464  bitmask = 1;
4465 
4466  for (i = 0; i < nitems; i++)
4467  {
4468  Datum itemvalue;
4469  char *value;
4470 
4471  /* Get source element, checking for NULL */
4472  if (bitmap && (*bitmap & bitmask) == 0)
4473  {
4474  /* if null_string is NULL, we just ignore null elements */
4475  if (null_string != NULL)
4476  {
4477  if (printed)
4478  appendStringInfo(&buf, "%s%s", fldsep, null_string);
4479  else
4480  appendStringInfoString(&buf, null_string);
4481  printed = true;
4482  }
4483  }
4484  else
4485  {
4486  itemvalue = fetch_att(p, typbyval, typlen);
4487 
4488  value = OutputFunctionCall(&my_extra->proc, itemvalue);
4489 
4490  if (printed)
4491  appendStringInfo(&buf, "%s%s", fldsep, value);
4492  else
4493  appendStringInfoString(&buf, value);
4494  printed = true;
4495 
4496  p = att_addlength_pointer(p, typlen, p);
4497  p = (char *) att_align_nominal(p, typalign);
4498  }
4499 
4500  /* advance bitmap pointer if any */
4501  if (bitmap)
4502  {
4503  bitmask <<= 1;
4504  if (bitmask == 0x100)
4505  {
4506  bitmap++;
4507  bitmask = 1;
4508  }
4509  }
4510  }
4511 
4512  result = cstring_to_text_with_len(buf.data, buf.len);
4513  pfree(buf.data);
4514 
4515  return result;
4516 }
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
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:1662
bool typbyval
Definition: array.h:225
FmgrInfo * flinfo
Definition: fmgr.h:79
void pfree(void *pointer)
Definition: mcxt.c:936
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ARR_DIMS(a)
Definition: array.h:279
static struct @121 value
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
#define ARR_DATA_PTR(a)
Definition: array.h:307
int16 typlen
Definition: array.h:224
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
char typdelim
Definition: array.h:227
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:132
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:172
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
uint8 bits8
Definition: c.h:313
uintptr_t Datum
Definition: postgres.h:372
Oid typioparam
Definition: array.h:228
void * fn_extra
Definition: fmgr.h:64
#define ARR_NDIM(a)
Definition: array.h:275
Oid typiofunc
Definition: array.h:229
char typalign
Definition: array.h:226
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:71
FmgrInfo proc
Definition: array.h:230
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
int i
Oid element_type
Definition: array.h:223
Definition: c.h:497
#define ARR_ELEMTYPE(a)
Definition: array.h:277
#define ARR_NULLBITMAP(a)
Definition: array.h:285
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:2094

◆ array_to_text_null()

Datum array_to_text_null ( PG_FUNCTION_ARGS  )

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

4376 {
4377  ArrayType *v;
4378  char *fldsep;
4379  char *null_string;
4380 
4381  /* returns NULL when first or second parameter is NULL */
4382  if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4383  PG_RETURN_NULL();
4384 
4385  v = PG_GETARG_ARRAYTYPE_P(0);
4386  fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4387 
4388  /* NULL null string is passed through as a null pointer */
4389  if (!PG_ARGISNULL(2))
4390  null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
4391  else
4392  null_string = NULL;
4393 
4394  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
4395 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4401
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
char * text_to_cstring(const text *t)
Definition: varlena.c:183
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ bpcharfastcmp_c()

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

Definition at line 2001 of file varlena.c.

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

Referenced by varstr_sortsupport().

2002 {
2003  BpChar *arg1 = DatumGetBpCharPP(x);
2004  BpChar *arg2 = DatumGetBpCharPP(y);
2005  char *a1p,
2006  *a2p;
2007  int len1,
2008  len2,
2009  result;
2010 
2011  a1p = VARDATA_ANY(arg1);
2012  a2p = VARDATA_ANY(arg2);
2013 
2014  len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2015  len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2016 
2017  result = memcmp(a1p, a2p, Min(len1, len2));
2018  if ((result == 0) && (len1 != len2))
2019  result = (len1 < len2) ? -1 : 1;
2020 
2021  /* We can't afford to leak memory here. */
2022  if (PointerGetDatum(arg1) != x)
2023  pfree(arg1);
2024  if (PointerGetDatum(arg2) != y)
2025  pfree(arg2);
2026 
2027  return result;
2028 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PointerGetDatum(X)
Definition: postgres.h:562
#define Min(x, y)
Definition: c.h:812
void pfree(void *pointer)
Definition: mcxt.c:936
int bpchartruelen(char *s, int len)
Definition: varchar.c:660
#define DatumGetBpCharPP(X)
Definition: fmgr.h:257
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2710 of file varlena.c.

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

2711 {
2712  text *arg1 = PG_GETARG_TEXT_PP(0);
2713  text *arg2 = PG_GETARG_TEXT_PP(1);
2714  int result;
2715 
2716  result = internal_text_pattern_compare(arg1, arg2);
2717 
2718  PG_FREE_IF_COPY(arg1, 0);
2719  PG_FREE_IF_COPY(arg2, 1);
2720 
2721  PG_RETURN_INT32(result);
2722 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2624
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2726 of file varlena.c.

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

2727 {
2729  MemoryContext oldcontext;
2730 
2731  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2732 
2733  /* Use generic string SortSupport, forcing "C" collation */
2734  varstr_sortsupport(ssup, C_COLLATION_OID, false);
2735 
2736  MemoryContextSwitchTo(oldcontext);
2737 
2738  PG_RETURN_VOID();
2739 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar)
Definition: varlena.c:1808
#define PG_RETURN_VOID()
Definition: fmgr.h:309
#define C_COLLATION_OID
Definition: pg_collation.h:78

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

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

1767 {
1768  text *arg1 = PG_GETARG_TEXT_PP(0);
1769  text *arg2 = PG_GETARG_TEXT_PP(1);
1770  int32 result;
1771 
1772  result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1773 
1774  PG_FREE_IF_COPY(arg1, 0);
1775  PG_FREE_IF_COPY(arg2, 1);
1776 
1777  PG_RETURN_INT32(result);
1778 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
#define PG_GET_COLLATION()
Definition: fmgr.h:163
signed int int32
Definition: c.h:294
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1781 of file varlena.c.

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

1782 {
1784  Oid collid = ssup->ssup_collation;
1785  MemoryContext oldcontext;
1786 
1787  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1788 
1789  /* Use generic string SortSupport */
1790  varstr_sortsupport(ssup, collid, false);
1791 
1792  MemoryContextSwitchTo(oldcontext);
1793 
1794  PG_RETURN_VOID();
1795 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
unsigned int Oid
Definition: postgres_ext.h:31
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar)
Definition: varlena.c:1808
#define PG_RETURN_VOID()
Definition: fmgr.h:309

◆ build_concat_foutcache()

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

Definition at line 4746 of file varlena.c.

References elog, ERROR, FunctionCallInfoData::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().

4747 {
4748  FmgrInfo *foutcache;
4749  int i;
4750 
4751  /* We keep the info in fn_mcxt so it survives across calls */
4752  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4753  PG_NARGS() * sizeof(FmgrInfo));
4754 
4755  for (i = argidx; i < PG_NARGS(); i++)
4756  {
4757  Oid valtype;
4758  Oid typOutput;
4759  bool typIsVarlena;
4760 
4761  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
4762  if (!OidIsValid(valtype))
4763  elog(ERROR, "could not determine data type of concat() input");
4764 
4765  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
4766  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
4767  }
4768 
4769  fcinfo->flinfo->fn_extra = foutcache;
4770 
4771  return foutcache;
4772 }
Definition: fmgr.h:56
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2665
MemoryContext fn_mcxt
Definition: fmgr.h:65
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:586
FmgrInfo * flinfo
Definition: fmgr.h:79
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:132
struct FmgrInfo FmgrInfo
#define PG_NARGS()
Definition: fmgr.h:168
void * fn_extra
Definition: fmgr.h:64
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
int i
#define elog
Definition: elog.h:219

◆ bytea_catenate()

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

Definition at line 2780 of file varlena.c.

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

Referenced by bytea_overlay(), and byteacat().

2781 {
2782  bytea *result;
2783  int len1,
2784  len2,
2785  len;
2786  char *ptr;
2787 
2788  len1 = VARSIZE_ANY_EXHDR(t1);
2789  len2 = VARSIZE_ANY_EXHDR(t2);
2790 
2791  /* paranoia ... probably should throw error instead? */
2792  if (len1 < 0)
2793  len1 = 0;
2794  if (len2 < 0)
2795  len2 = 0;
2796 
2797  len = len1 + len2 + VARHDRSZ;
2798  result = (bytea *) palloc(len);
2799 
2800  /* Set size of result string... */
2801  SET_VARSIZE(result, len);
2802 
2803  /* Fill data field of result string... */
2804  ptr = VARDATA(result);
2805  if (len1 > 0)
2806  memcpy(ptr, VARDATA_ANY(t1), len1);
2807  if (len2 > 0)
2808  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
2809 
2810  return result;
2811 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void * palloc(Size size)
Definition: mcxt.c:835
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ bytea_overlay()

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

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

2938 {
2939  bytea *result;
2940  bytea *s1;
2941  bytea *s2;
2942  int sp_pl_sl;
2943 
2944  /*
2945  * Check for possible integer-overflow cases. For negative sp, throw a
2946  * "substring length" error because that's what should be expected
2947  * according to the spec's definition of OVERLAY().
2948  */
2949  if (sp <= 0)
2950  ereport(ERROR,
2951  (errcode(ERRCODE_SUBSTRING_ERROR),
2952  errmsg("negative substring length not allowed")));
2953  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
2954  ereport(ERROR,
2955  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2956  errmsg("integer out of range")));
2957 
2958  s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
2959  s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
2960  result = bytea_catenate(s1, t2);
2961  result = bytea_catenate(result, s2);
2962 
2963  return result;
2964 }
#define PointerGetDatum(X)
Definition: postgres.h:562
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:2780
int errcode(int sqlerrcode)
Definition: elog.c:575
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:2855
#define ERROR
Definition: elog.h:43
char * s1
#define ereport(elevel, rest)
Definition: elog.h:122
char * s2
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:89
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 3654 of file varlena.c.

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

3655 {
3657  MemoryContext oldcontext;
3658 
3659  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
3660 
3661  /* Use generic string SortSupport, forcing "C" collation */
3662  varstr_sortsupport(ssup, C_COLLATION_OID, false);
3663 
3664  MemoryContextSwitchTo(oldcontext);
3665 
3666  PG_RETURN_VOID();
3667 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar)
Definition: varlena.c:1808
#define PG_RETURN_VOID()
Definition: fmgr.h:309
#define C_COLLATION_OID
Definition: pg_collation.h:78

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

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

484 {
486 
487  /* cannot be called directly because of internal-type argument */
488  Assert(AggCheckCallContext(fcinfo, NULL));
489 
490  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
491 
492  if (state != NULL)
493  {
494  bytea *result;
495 
496  result = (bytea *) palloc(state->len + VARHDRSZ);
497  SET_VARSIZE(result, state->len + VARHDRSZ);
498  memcpy(VARDATA(result), state->data, state->len);
499  PG_RETURN_BYTEA_P(result);
500  }
501  else
502  PG_RETURN_NULL();
503 }
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define Assert(condition)
Definition: c.h:680
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4127
void * palloc(Size size)
Definition: mcxt.c:835
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

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

452 {
454 
455  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
456 
457  /* Append the value unless null. */
458  if (!PG_ARGISNULL(1))
459  {
461 
462  /* On the first time through, we ignore the delimiter. */
463  if (state == NULL)
464  state = makeStringAggState(fcinfo);
465  else if (!PG_ARGISNULL(2))
466  {
467  bytea *delim = PG_GETARG_BYTEA_PP(2);
468 
470  }
471 
473  }
474 
475  /*
476  * The transition type for string_agg() is declared to be "internal",
477  * which is a pass-by-value type the same size as a pointer.
478  */
479  PG_RETURN_POINTER(state);
480 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
static struct @121 value
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:4674
Definition: c.h:497
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 2832 of file varlena.c.

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

2833 {
2835  PG_GETARG_INT32(1),
2836  PG_GETARG_INT32(2),
2837  false));
2838 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:2855

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 2846 of file varlena.c.

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

2847 {
2849  PG_GETARG_INT32(1),
2850  -1,
2851  true));
2852 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:2855

◆ bytea_substring()

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

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

2859 {
2860  int S1; /* adjusted start position */
2861  int L1; /* adjusted substring length */
2862 
2863  S1 = Max(S, 1);
2864 
2865  if (length_not_specified)
2866  {
2867  /*
2868  * Not passed a length - DatumGetByteaPSlice() grabs everything to the
2869  * end of the string if we pass it a negative value for length.
2870  */
2871  L1 = -1;
2872  }
2873  else
2874  {
2875  /* end position */
2876  int E = S + L;
2877 
2878  /*
2879  * A negative value for L is the only way for the end position to be
2880  * before the start. SQL99 says to throw an error.
2881  */
2882  if (E < S)
2883  ereport(ERROR,
2884  (errcode(ERRCODE_SUBSTRING_ERROR),
2885  errmsg("negative substring length not allowed")));
2886 
2887  /*
2888  * A zero or negative value for the end position can happen if the
2889  * start was negative or one. SQL99 says to return a zero-length
2890  * string.
2891  */
2892  if (E < 1)
2893  return PG_STR_GET_BYTEA("");
2894 
2895  L1 = E - S1;
2896  }
2897 
2898  /*
2899  * If the start position is past the end of the string, SQL99 says to
2900  * return a zero-length string -- DatumGetByteaPSlice() will do that for
2901  * us. Convert to zero-based starting position
2902  */
2903  return DatumGetByteaPSlice(str, S1 - 1, L1);
2904 }
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:267
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:2813
#define ERROR
Definition: elog.h:43
#define S(n, x)
Definition: sha1.c:55
#define ereport(elevel, rest)
Definition: elog.h:122
#define Max(x, y)
Definition: c.h:806
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 2765 of file varlena.c.

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

2766 {
2767  bytea *t1 = PG_GETARG_BYTEA_PP(0);
2768  bytea *t2 = PG_GETARG_BYTEA_PP(1);
2769 
2771 }
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:2780
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
Definition: c.h:497

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

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

3633 {
3634  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3635  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3636  int len1,
3637  len2;
3638  int cmp;
3639 
3640  len1 = VARSIZE_ANY_EXHDR(arg1);
3641  len2 = VARSIZE_ANY_EXHDR(arg2);
3642 
3643  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3644  if ((cmp == 0) && (len1 != len2))
3645  cmp = (len1 < len2) ? -1 : 1;
3646 
3647  PG_FREE_IF_COPY(arg1, 0);
3648  PG_FREE_IF_COPY(arg2, 1);
3649 
3650  PG_RETURN_INT32(cmp);
3651 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define Min(x, y)
Definition: c.h:812
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497
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 3488 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().

3489 {
3490  Datum arg1 = PG_GETARG_DATUM(0);
3491  Datum arg2 = PG_GETARG_DATUM(1);
3492  bool result;
3493  Size len1,
3494  len2;
3495 
3496  /*
3497  * We can use a fast path for unequal lengths, which might save us from
3498  * having to detoast one or both values.
3499  */
3500  len1 = toast_raw_datum_size(arg1);
3501  len2 = toast_raw_datum_size(arg2);
3502  if (len1 != len2)
3503  result = false;
3504  else
3505  {
3506  bytea *barg1 = DatumGetByteaPP(arg1);
3507  bytea *barg2 = DatumGetByteaPP(arg2);
3508 
3509  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3510  len1 - VARHDRSZ) == 0);
3511 
3512  PG_FREE_IF_COPY(barg1, 0);
3513  PG_FREE_IF_COPY(barg2, 1);
3514  }
3515 
3516  PG_RETURN_BOOL(result);
3517 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define VARHDRSZ
Definition: c.h:503
#define DatumGetByteaPP(X)
Definition: fmgr.h:255
Size toast_raw_datum_size(Datum value)
Definition: tuptoaster.c:353
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
size_t Size
Definition: c.h:414
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

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

3613 {
3614  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3615  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3616  int len1,
3617  len2;
3618  int cmp;
3619 
3620  len1 = VARSIZE_ANY_EXHDR(arg1);
3621  len2 = VARSIZE_ANY_EXHDR(arg2);
3622 
3623  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3624 
3625  PG_FREE_IF_COPY(arg1, 0);
3626  PG_FREE_IF_COPY(arg2, 1);
3627 
3628  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
3629 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define Min(x, y)
Definition: c.h:812
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497
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 3046 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.

3047 {
3048  bytea *v = PG_GETARG_BYTEA_PP(0);
3049  int32 n = PG_GETARG_INT32(1);
3050  int byteNo,
3051  bitNo;
3052  int len;
3053  int byte;
3054 
3055  len = VARSIZE_ANY_EXHDR(v);
3056 
3057  if (n < 0 || n >= len * 8)
3058  ereport(ERROR,
3059  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3060  errmsg("index %d out of valid range, 0..%d",
3061  n, len * 8 - 1)));
3062 
3063  byteNo = n / 8;
3064  bitNo = n % 8;
3065 
3066  byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3067 
3068  if (byte & (1 << bitNo))
3069  PG_RETURN_INT32(1);
3070  else
3071  PG_RETURN_INT32(0);
3072 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
signed int int32
Definition: c.h:294
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define byte(x, n)
Definition: rijndael.c:68
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

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

3018 {
3019  bytea *v = PG_GETARG_BYTEA_PP(0);
3020  int32 n = PG_GETARG_INT32(1);
3021  int len;
3022  int byte;
3023 
3024  len = VARSIZE_ANY_EXHDR(v);
3025 
3026  if (n < 0 || n >= len)
3027  ereport(ERROR,
3028  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3029  errmsg("index %d out of valid range, 0..%d",
3030  n, len - 1)));
3031 
3032  byte = ((unsigned char *) VARDATA_ANY(v))[n];
3033 
3034  PG_RETURN_INT32(byte);
3035 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
signed int int32
Definition: c.h:294
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define byte(x, n)
Definition: rijndael.c:68
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

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

3593 {
3594  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3595  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3596  int len1,
3597  len2;
3598  int cmp;
3599 
3600  len1 = VARSIZE_ANY_EXHDR(arg1);
3601  len2 = VARSIZE_ANY_EXHDR(arg2);
3602 
3603  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3604 
3605  PG_FREE_IF_COPY(arg1, 0);
3606  PG_FREE_IF_COPY(arg2, 1);
3607 
3608  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
3609 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define Min(x, y)
Definition: c.h:812
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497
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 256 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().

257 {
258  char *inputText = PG_GETARG_CSTRING(0);
259  char *tp;
260  char *rp;
261  int bc;
262  bytea *result;
263 
264  /* Recognize hex input */
265  if (inputText[0] == '\\' && inputText[1] == 'x')
266  {
267  size_t len = strlen(inputText);
268 
269  bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */
270  result = palloc(bc);
271  bc = hex_decode(inputText + 2, len - 2, VARDATA(result));
272  SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
273 
274  PG_RETURN_BYTEA_P(result);
275  }
276 
277  /* Else, it's the traditional escaped style */
278  for (bc = 0, tp = inputText; *tp != '\0'; bc++)
279  {
280  if (tp[0] != '\\')
281  tp++;
282  else if ((tp[0] == '\\') &&
283  (tp[1] >= '0' && tp[1] <= '3') &&
284  (tp[2] >= '0' && tp[2] <= '7') &&
285  (tp[3] >= '0' && tp[3] <= '7'))
286  tp += 4;
287  else if ((tp[0] == '\\') &&
288  (tp[1] == '\\'))
289  tp += 2;
290  else
291  {
292  /*
293  * one backslash, not followed by another or ### valid octal
294  */
295  ereport(ERROR,
296  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
297  errmsg("invalid input syntax for type %s", "bytea")));
298  }
299  }
300 
301  bc += VARHDRSZ;
302 
303  result = (bytea *) palloc(bc);
304  SET_VARSIZE(result, bc);
305 
306  tp = inputText;
307  rp = VARDATA(result);
308  while (*tp != '\0')
309  {
310  if (tp[0] != '\\')
311  *rp++ = *tp++;
312  else if ((tp[0] == '\\') &&
313  (tp[1] >= '0' && tp[1] <= '3') &&
314  (tp[2] >= '0' && tp[2] <= '7') &&
315  (tp[3] >= '0' && tp[3] <= '7'))
316  {
317  bc = VAL(tp[1]);
318  bc <<= 3;
319  bc += VAL(tp[2]);
320  bc <<= 3;
321  *rp++ = bc + VAL(tp[3]);
322 
323  tp += 4;
324  }
325  else if ((tp[0] == '\\') &&
326  (tp[1] == '\\'))
327  {
328  *rp++ = '\\';
329  tp += 2;
330  }
331  else
332  {
333  /*
334  * We should never get here. The first pass should not allow it.
335  */
336  ereport(ERROR,
337  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
338  errmsg("invalid input syntax for type %s", "bytea")));
339  }
340  }
341 
342  PG_RETURN_BYTEA_P(result);
343 }
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
unsigned hex_decode(const char *src, unsigned len, char *dst)
Definition: encode.c:156
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void * palloc(Size size)
Definition: mcxt.c:835
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
#define VAL(CH)
Definition: varlena.c:241
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

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

3573 {
3574  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3575  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3576  int len1,
3577  len2;
3578  int cmp;
3579 
3580  len1 = VARSIZE_ANY_EXHDR(arg1);
3581  len2 = VARSIZE_ANY_EXHDR(arg2);
3582 
3583  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3584 
3585  PG_FREE_IF_COPY(arg1, 0);
3586  PG_FREE_IF_COPY(arg2, 1);
3587 
3588  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
3589 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define Min(x, y)
Definition: c.h:812
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497
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 3552 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().

3553 {
3554  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3555  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3556  int len1,
3557  len2;
3558  int cmp;
3559 
3560  len1 = VARSIZE_ANY_EXHDR(arg1);
3561  len2 = VARSIZE_ANY_EXHDR(arg2);
3562 
3563  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3564 
3565  PG_FREE_IF_COPY(arg1, 0);
3566  PG_FREE_IF_COPY(arg2, 1);
3567 
3568  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
3569 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define Min(x, y)
Definition: c.h:812
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497
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 3520 of file varlena.c.

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

3521 {
3522  Datum arg1 = PG_GETARG_DATUM(0);
3523  Datum arg2 = PG_GETARG_DATUM(1);
3524  bool result;
3525  Size len1,
3526  len2;
3527 
3528  /*
3529  * We can use a fast path for unequal lengths, which might save us from
3530  * having to detoast one or both values.
3531  */
3532  len1 = toast_raw_datum_size(arg1);
3533  len2 = toast_raw_datum_size(arg2);
3534  if (len1 != len2)
3535  result = true;
3536  else
3537  {
3538  bytea *barg1 = DatumGetByteaPP(arg1);
3539  bytea *barg2 = DatumGetByteaPP(arg2);
3540 
3541  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3542  len1 - VARHDRSZ) != 0);
3543 
3544  PG_FREE_IF_COPY(barg1, 0);
3545  PG_FREE_IF_COPY(barg2, 1);
3546  }
3547 
3548  PG_RETURN_BOOL(result);
3549 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define VARHDRSZ
Definition: c.h:503
#define DatumGetByteaPP(X)
Definition: fmgr.h:255
Size toast_raw_datum_size(Datum value)
Definition: tuptoaster.c:353
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
size_t Size
Definition: c.h:414
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 2749 of file varlena.c.

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

2750 {
2751  Datum str = PG_GETARG_DATUM(0);
2752 
2753  /* We need not detoast the input at all */
2755 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define VARHDRSZ
Definition: c.h:503
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
Size toast_raw_datum_size(Datum value)
Definition: tuptoaster.c:353
uintptr_t Datum
Definition: postgres.h:372

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 352 of file varlena.c.

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

Referenced by patternsel(), and prefix_quals().

353 {
354  bytea *vlena = PG_GETARG_BYTEA_PP(0);
355  char *result;
356  char *rp;
357 
359  {
360  /* Print hex format */
361  rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
362  *rp++ = '\\';
363  *rp++ = 'x';
364  rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
365  }
366  else if (bytea_output == BYTEA_OUTPUT_ESCAPE)
367  {
368  /* Print traditional escaped format */
369  char *vp;
370  int len;
371  int i;
372 
373  len = 1; /* empty string has 1 char */
374  vp = VARDATA_ANY(vlena);
375  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
376  {
377  if (*vp == '\\')
378  len += 2;
379  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
380  len += 4;
381  else
382  len++;
383  }
384  rp = result = (char *) palloc(len);
385  vp = VARDATA_ANY(vlena);
386  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
387  {
388  if (*vp == '\\')
389  {
390  *rp++ = '\\';
391  *rp++ = '\\';
392  }
393  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
394  {
395  int val; /* holds unprintable chars */
396 
397  val = *vp;
398  rp[0] = '\\';
399  rp[3] = DIG(val & 07);
400  val >>= 3;
401  rp[2] = DIG(val & 07);
402  val >>= 3;
403  rp[1] = DIG(val & 03);
404  rp += 4;
405  }
406  else
407  *rp++ = *vp;
408  }
409  }
410  else
411  {
412  elog(ERROR, "unrecognized bytea_output setting: %d",
413  bytea_output);
414  rp = result = NULL; /* keep compiler quiet */
415  }
416  *rp = '\0';
417  PG_RETURN_CSTRING(result);
418 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
unsigned hex_encode(const char *src, unsigned len, char *dst)
Definition: encode.c:126
#define ERROR
Definition: elog.h:43
int bytea_output
Definition: varlena.c:42
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void * palloc(Size size)
Definition: mcxt.c:835
int i
Definition: c.h:497
#define elog
Definition: elog.h:219
long val
Definition: informix.c:689
#define DIG(VAL)
Definition: varlena.c:242

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 2914 of file varlena.c.

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

2915 {
2916  bytea *t1 = PG_GETARG_BYTEA_PP(0);
2917  bytea *t2 = PG_GETARG_BYTEA_PP(1);
2918  int sp = PG_GETARG_INT32(2); /* substring start position */
2919  int sl = PG_GETARG_INT32(3); /* substring length */
2920 
2921  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
2922 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:2937
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
Definition: c.h:497

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 2925 of file varlena.c.

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

2926 {
2927  bytea *t1 = PG_GETARG_BYTEA_PP(0);
2928  bytea *t2 = PG_GETARG_BYTEA_PP(1);
2929  int sp = PG_GETARG_INT32(2); /* substring start position */
2930  int sl;
2931 
2932  sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
2933  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
2934 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:2937
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 2973 of file varlena.c.

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

2974 {
2975  bytea *t1 = PG_GETARG_BYTEA_PP(0);
2976  bytea *t2 = PG_GETARG_BYTEA_PP(1);
2977  int pos;
2978  int px,
2979  p;
2980  int len1,
2981  len2;
2982  char *p1,
2983  *p2;
2984 
2985  len1 = VARSIZE_ANY_EXHDR(t1);
2986  len2 = VARSIZE_ANY_EXHDR(t2);
2987 
2988  if (len2 <= 0)
2989  PG_RETURN_INT32(1); /* result for empty pattern */
2990 
2991  p1 = VARDATA_ANY(t1);
2992  p2 = VARDATA_ANY(t2);
2993 
2994  pos = 0;
2995  px = (len1 - len2);
2996  for (p = 0; p <= px; p++)
2997  {
2998  if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
2999  {
3000  pos = p + 1;
3001  break;
3002  };
3003  p1++;
3004  };
3005 
3006  PG_RETURN_INT32(pos);
3007 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
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:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

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

425 {
427  bytea *result;
428  int nbytes;
429 
430  nbytes = buf->len - buf->cursor;
431  result = (bytea *) palloc(nbytes + VARHDRSZ);
432  SET_VARSIZE(result, nbytes + VARHDRSZ);
433  pq_copymsgbytes(buf, VARDATA(result), nbytes);
434  PG_RETURN_BYTEA_P(result);
435 }
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
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:835
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ byteasend()

Datum byteasend ( PG_FUNCTION_ARGS  )

Definition at line 443 of file varlena.c.

References PG_GETARG_BYTEA_P_COPY, and PG_RETURN_BYTEA_P.

Referenced by pg_dependencies_send(), and pg_ndistinct_send().

444 {
445  bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
446 
447  PG_RETURN_BYTEA_P(vlena);
448 }
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:278
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
Definition: c.h:497

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

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

3116 {
3117  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3118  int32 n = PG_GETARG_INT32(1);
3119  int32 newBit = PG_GETARG_INT32(2);
3120  int len;
3121  int oldByte,
3122  newByte;
3123  int byteNo,
3124  bitNo;
3125 
3126  len = VARSIZE(res) - VARHDRSZ;
3127 
3128  if (n < 0 || n >= len * 8)
3129  ereport(ERROR,
3130  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3131  errmsg("index %d out of valid range, 0..%d",
3132  n, len * 8 - 1)));
3133 
3134  byteNo = n / 8;
3135  bitNo = n % 8;
3136 
3137  /*
3138  * sanity check!
3139  */
3140  if (newBit != 0 && newBit != 1)
3141  ereport(ERROR,
3142  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3143  errmsg("new bit must be 0 or 1")));
3144 
3145  /*
3146  * Update the byte.
3147  */
3148  oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3149 
3150  if (newBit == 0)
3151  newByte = oldByte & (~(1 << bitNo));
3152  else
3153  newByte = oldByte | (1 << bitNo);
3154 
3155  ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3156 
3157  PG_RETURN_BYTEA_P(res);
3158 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARSIZE(PTR)
Definition: postgres.h:304
#define VARHDRSZ
Definition: c.h:503
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:278
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
signed int int32
Definition: c.h:294
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

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

3084 {
3085  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3086  int32 n = PG_GETARG_INT32(1);
3087  int32 newByte = PG_GETARG_INT32(2);
3088  int len;
3089 
3090  len = VARSIZE(res) - VARHDRSZ;
3091 
3092  if (n < 0 || n >= len)
3093  ereport(ERROR,
3094  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3095  errmsg("index %d out of valid range, 0..%d",
3096  n, len - 1)));
3097 
3098  /*
3099  * Now set the byte.
3100  */
3101  ((unsigned char *) VARDATA(res))[n] = newByte;
3102 
3103  PG_RETURN_BYTEA_P(res);
3104 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARSIZE(PTR)
Definition: postgres.h:304
#define VARHDRSZ
Definition: c.h:503
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:278
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
signed int int32
Definition: c.h:294
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ charlen_to_bytelen()

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

Definition at line 736 of file varlena.c.

References pg_database_encoding_max_length(), and pg_mblen().

Referenced by appendStringInfoRegexpSubstr(), replace_text(), replace_text_regexp(), and text_to_array_internal().

737 {
739  {
740  /* Optimization for single-byte encodings */
741  return n;
742  }
743  else
744  {
745  const char *s;
746 
747  for (s = p; n > 0; n--)
748  s += pg_mblen(s);
749 
750  return s - p;
751  }
752 }
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
int pg_mblen(const char *mbstr)
Definition: mbutils.c:760

◆ check_replace_text_has_escape_char()

static bool check_replace_text_has_escape_char ( const text replace_text)
static

Definition at line 3773 of file varlena.c.

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

Referenced by replace_text_regexp().

3774 {
3775  const char *p = VARDATA_ANY(replace_text);
3776  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
3777 
3779  {
3780  for (; p < p_end; p++)
3781  {
3782  if (*p == '\\')
3783  return true;
3784  }
3785  }
3786  else
3787  {
3788  for (; p < p_end; p += pg_mblen(p))
3789  {
3790  if (*p == '\\')
3791  return true;
3792  }
3793  }
3794 
3795  return false;
3796 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
int pg_mblen(const char *mbstr)
Definition: mbutils.c:760
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340

◆ concat_internal()

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

Definition at line 4784 of file varlena.c.

References appendStringInfoString(), array_to_text_internal(), Assert, build_concat_foutcache(), cstring_to_text_with_len(), StringInfoData::data, FunctionCallInfoData::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().

4786 {
4787  text *result;
4789  FmgrInfo *foutcache;
4790  bool first_arg = true;
4791  int i;
4792 
4793  /*
4794  * concat(VARIADIC some-array) is essentially equivalent to
4795  * array_to_text(), ie concat the array elements with the given separator.
4796  * So we just pass the case off to that code.
4797  */
4798  if (get_fn_expr_variadic(fcinfo->flinfo))
4799  {
4800  ArrayType *arr;
4801 
4802  /* Should have just the one argument */
4803  Assert(argidx == PG_NARGS() - 1);
4804 
4805  /* concat(VARIADIC NULL) is defined as NULL */
4806  if (PG_ARGISNULL(argidx))
4807  return NULL;
4808 
4809  /*
4810  * Non-null argument had better be an array. We assume that any call
4811  * context that could let get_fn_expr_variadic return true will have
4812  * checked that a VARIADIC-labeled parameter actually is an array. So
4813  * it should be okay to just Assert that it's an array rather than
4814  * doing a full-fledged error check.
4815  */
4817 
4818  /* OK, safe to fetch the array value */
4819  arr = PG_GETARG_ARRAYTYPE_P(argidx);
4820 
4821  /*
4822  * And serialize the array. We tell array_to_text to ignore null
4823  * elements, which matches the behavior of the loop below.
4824  */
4825  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
4826  }
4827 
4828  /* Normal case without explicit VARIADIC marker */
4829  initStringInfo(&str);
4830 
4831  /* Get output function info, building it if first time through */
4832  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
4833  if (foutcache == NULL)
4834  foutcache = build_concat_foutcache(fcinfo, argidx);
4835 
4836  for (i = argidx; i < PG_NARGS(); i++)
4837  {
4838  if (!PG_ARGISNULL(i))
4839  {
4841 
4842  /* add separator if appropriate */
4843  if (first_arg)
4844  first_arg = false;
4845  else
4846  appendStringInfoString(&str, sepstr);
4847 
4848  /* call the appropriate type output function, append the result */
4850  OutputFunctionCall(&foutcache[i], value));
4851  }
4852  }
4853 
4854  result = cstring_to_text_with_len(str.data, str.len);
4855  pfree(str.data);
4856 
4857  return result;
4858 }
Definition: fmgr.h:56
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2038
#define OidIsValid(objectId)
Definition: c.h:586
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1662
FmgrInfo * flinfo
Definition: fmgr.h:79
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
void pfree(void *pointer)
Definition: mcxt.c:936
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
static struct @121 value
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:4401
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
uintptr_t Datum
Definition: postgres.h:372
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define Assert(condition)
Definition: c.h:680
#define PG_NARGS()
Definition: fmgr.h:168
void * fn_extra
Definition: fmgr.h:64
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2590
int i
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:4746
Definition: c.h:497

◆ cstring_to_text()

text* cstring_to_text ( const char *  s)

Definition at line 150 of file varlena.c.

References cstring_to_text_with_len().

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

151 {
152  return cstring_to_text_with_len(s, strlen(s));
153 }
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162

◆ cstring_to_text_with_len()

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

Definition at line 162 of file varlena.c.

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

Referenced by array_to_json(), array_to_json_pretty(), array_to_text_internal(), compute_tsvector_stats(), concat_internal(), cstring_to_text(), cstring_to_xmltype(), do_text_output_multiline(), dotrim(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), elements_worker_jsonb(), ExecEvalXmlExpr(), fsm_page_contents(), get_array_element_end(), get_array_end(), get_jsonb_path_all(), get_object_end(), get_object_field_end(), get_scalar(), gin_extract_tsquery(), gin_extract_tsvector(), hstore_akeys(), hstore_avals(), hstore_each(), hstore_fetchval(), hstore_skeys(), hstore_slice_to_array(), hstore_svals(), hstore_to_array_internal(), hstore_to_json(), hstore_to_json_loose(), json_build_array(), json_build_array_noargs(), json_build_object(), json_build_object_noargs(), json_object(), json_object_two_arg(), json_recv(), json_strip_nulls(), jsonb_array_element_text(), jsonb_object_field_text(), jsonb_pretty(), leftmostvalue_text(), LogicalOutputWrite(), parse_ident(), pg_gen_salt(), pg_gen_salt_rounds(), replace_text(), replace_text_regexp(), row_to_json(), row_to_json_pretty(), serialize_deflist(), 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().

163 {
164  text *result = (text *) palloc(len + VARHDRSZ);
165 
166  SET_VARSIZE(result, len + VARHDRSZ);
167  memcpy(VARDATA(result), s, len);
168 
169  return result;
170 }
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
void * palloc(Size size)
Definition: mcxt.c:835
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ internal_text_pattern_compare()

static int internal_text_pattern_compare ( text arg1,
text arg2 
)
static

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

2625 {
2626  int result;
2627  int len1,
2628  len2;
2629 
2630  len1 = VARSIZE_ANY_EXHDR(arg1);
2631  len2 = VARSIZE_ANY_EXHDR(arg2);
2632 
2633  result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
2634  if (result != 0)
2635  return result;
2636  else if (len1 < len2)
2637  return -1;
2638  else if (len1 > len2)
2639  return 1;
2640  else
2641  return 0;
2642 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define Min(x, y)
Definition: c.h:812
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 4674 of file varlena.c.

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

Referenced by bytea_string_agg_transfn(), and string_agg_transfn().

4675 {
4676  StringInfo state;
4677  MemoryContext aggcontext;
4678  MemoryContext oldcontext;
4679 
4680  if (!AggCheckCallContext(fcinfo, &aggcontext))
4681  {
4682  /* cannot be called directly because of internal-type argument */
4683  elog(ERROR, "string_agg_transfn called in non-aggregate context");
4684  }
4685 
4686  /*
4687  * Create state in aggregate context. It'll stay there across subsequent
4688  * calls.
4689  */
4690  oldcontext = MemoryContextSwitchTo(aggcontext);
4691  state = makeStringInfo();
4692  MemoryContextSwitchTo(oldcontext);
4693 
4694  return state;
4695 }
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ERROR
Definition: elog.h:43
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4127
#define elog
Definition: elog.h:219

◆ md5_bytea()

Datum md5_bytea ( PG_FUNCTION_ARGS  )

Definition at line 4599 of file varlena.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, MD5_HASH_LEN, PG_GETARG_BYTEA_PP, pg_md5_hash(), PG_RETURN_TEXT_P, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

4600 {
4601  bytea *in = PG_GETARG_BYTEA_PP(0);
4602  size_t len;
4603  char hexsum[MD5_HASH_LEN + 1];
4604 
4605  len = VARSIZE_ANY_EXHDR(in);
4606  if (pg_md5_hash(VARDATA_ANY(in), len, hexsum) == false)
4607  ereport(ERROR,
4608  (errcode(ERRCODE_OUT_OF_MEMORY),
4609  errmsg("out of memory")));
4610 
4612 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define MD5_HASH_LEN
Definition: varlena.c:4572
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
bool pg_md5_hash(const void *buff, size_t len, char *hexsum)
Definition: md5.c:293
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:272
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ md5_text()

Datum md5_text ( PG_FUNCTION_ARGS  )

Definition at line 4575 of file varlena.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, MD5_HASH_LEN, PG_GETARG_TEXT_PP, pg_md5_hash(), PG_RETURN_TEXT_P, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

4576 {
4577  text *in_text = PG_GETARG_TEXT_PP(0);
4578  size_t len;
4579  char hexsum[MD5_HASH_LEN + 1];
4580 
4581  /* Calculate the length of the buffer using varlena metadata */
4582  len = VARSIZE_ANY_EXHDR(in_text);
4583 
4584  /* get the hash result */
4585  if (pg_md5_hash(VARDATA_ANY(in_text), len, hexsum) == false)
4586  ereport(ERROR,
4587  (errcode(ERRCODE_OUT_OF_MEMORY),
4588  errmsg("out of memory")));
4589 
4590  /* convert to text and return it */
4592 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define MD5_HASH_LEN
Definition: varlena.c:4572
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
bool pg_md5_hash(const void *buff, size_t len, char *hexsum)
Definition: md5.c:293
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3188 of file varlena.c.

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

Referenced by nameiclike(), and nameicnlike().

3189 {
3190  Name s = PG_GETARG_NAME(0);
3191 
3193 }
Definition: c.h:551
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
#define NameStr(name)
Definition: c.h:557
#define PG_GETARG_NAME(n)
Definition: fmgr.h:243

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

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

4621 {
4623  int32 result;
4624  int typlen;
4625 
4626  /* On first call, get the input type's typlen, and save at *fn_extra */
4627  if (fcinfo->flinfo->fn_extra == NULL)
4628  {
4629  /* Lookup the datatype of the supplied argument */
4630  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
4631 
4632  typlen = get_typlen(argtypeid);
4633  if (typlen == 0) /* should not happen */
4634  elog(ERROR, "cache lookup failed for type %u", argtypeid);
4635 
4636  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
4637  sizeof(int));
4638  *((int *) fcinfo->flinfo->fn_extra) = typlen;
4639  }
4640  else
4641  typlen = *((int *) fcinfo->flinfo->fn_extra);
4642 
4643  if (typlen == -1)
4644  {
4645  /* varlena type, possibly toasted */
4646  result = toast_datum_size(value);
4647  }
4648  else if (typlen == -2)
4649  {
4650  /* cstring */
4651  result = strlen(DatumGetCString(value)) + 1;
4652  }
4653  else
4654  {
4655  /* ordinary fixed-width type */
4656  result = typlen;
4657  }
4658 
4659  PG_RETURN_INT32(result);
4660 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:294
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:572
Size toast_datum_size(Datum value)
Definition: tuptoaster.c:409
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
static struct @121 value
uintptr_t Datum
Definition: postgres.h:372
int16 get_typlen(Oid typid)
Definition: lsyscache.c:1966
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
#define elog
Definition: elog.h:219

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

Definition at line 3690 of file varlena.c.

References appendBinaryStringInfo(), appendStringInfoText(), charlen_to_bytelen(), CHECK_FOR_INTERRUPTS, cstring_to_text_with_len(), StringInfoData::data, initStringInfo(), StringInfoData::len, TextPositionState::len1, TextPositionState::len2, pfree(), PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, generate_unaccent_rules::str, text_position_cleanup(), text_position_next(), text_position_setup(), VARDATA_ANY, and VARSIZE_ANY.

Referenced by execute_extension_script().

3691 {
3692  text *src_text = PG_GETARG_TEXT_PP(0);
3693  text *from_sub_text = PG_GETARG_TEXT_PP(1);
3694  text *to_sub_text = PG_GETARG_TEXT_PP(2);
3695  int src_text_len;
3696  int from_sub_text_len;
3698  text *ret_text;
3699  int start_posn;
3700  int curr_posn;
3701  int chunk_len;
3702  char *start_ptr;
3704 
3705  text_position_setup(src_text, from_sub_text, &state);
3706 
3707  /*
3708  * Note: we check the converted string length, not the original, because
3709  * they could be different if the input contained invalid encoding.
3710  */
3711  src_text_len = state.len1;
3712  from_sub_text_len = state.len2;
3713 
3714  /* Return unmodified source string if empty source or pattern */
3715  if (src_text_len < 1 || from_sub_text_len < 1)
3716  {
3717  text_position_cleanup(&state);
3718  PG_RETURN_TEXT_P(src_text);
3719  }
3720 
3721  start_posn = 1;
3722  curr_posn = text_position_next(1, &state);
3723 
3724  /* When the from_sub_text is not found, there is nothing to do. */
3725  if (curr_posn == 0)
3726  {
3727  text_position_cleanup(&state);
3728  PG_RETURN_TEXT_P(src_text);
3729  }
3730 
3731  /* start_ptr points to the start_posn'th character of src_text */
3732  start_ptr = VARDATA_ANY(src_text);
3733 
3734  initStringInfo(&str);
3735 
3736  do
3737  {
3739 
3740  /* copy the data skipped over by last text_position_next() */
3741  chunk_len = charlen_to_bytelen(start_ptr, curr_posn - start_posn);
3742  appendBinaryStringInfo(&str, start_ptr, chunk_len);
3743 
3744  appendStringInfoText(&str, to_sub_text);
3745 
3746  start_posn = curr_posn;
3747  start_ptr += chunk_len;
3748  start_posn += from_sub_text_len;
3749  start_ptr += charlen_to_bytelen(start_ptr, from_sub_text_len);
3750 
3751  curr_posn = text_position_next(start_posn, &state);
3752  }
3753  while (curr_posn > 0);
3754 
3755  /* copy trailing data */
3756  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
3757  appendBinaryStringInfo(&str, start_ptr, chunk_len);
3758 
3759  text_position_cleanup(&state);
3760 
3761  ret_text = cstring_to_text_with_len(str.data, str.len);
3762  pfree(str.data);
3763 
3764  PG_RETURN_TEXT_P(ret_text);
3765 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
static void text_position_setup(text *t1, text *t2, TextPositionState *state)
Definition: varlena.c:1119
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
void pfree(void *pointer)
Definition: mcxt.c:936
static int text_position_next(int start_pos, TextPositionState *state)
Definition: varlena.c:1231
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:736
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3676
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define VARSIZE_ANY(PTR)
Definition: postgres.h:334
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1365
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
Definition: c.h:497
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208

◆ replace_text_regexp()

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

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

3913 {
3914  text *ret_text;
3915  regex_t *re = (regex_t *) regexp;
3916  int src_text_len = VARSIZE_ANY_EXHDR(src_text);
3919  pg_wchar *data;
3920  size_t data_len;
3921  int search_start;
3922  int data_pos;
3923  char *start_ptr;
3924  bool have_escape;
3925 
3926  initStringInfo(&buf);
3927 
3928  /* Convert data string to wide characters. */
3929  data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
3930  data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
3931 
3932  /* Check whether replace_text has escape char. */
3933  have_escape = check_replace_text_has_escape_char(replace_text);
3934 
3935  /* start_ptr points to the data_pos'th character of src_text */
3936  start_ptr = (char *) VARDATA_ANY(src_text);
3937  data_pos = 0;
3938 
3939  search_start = 0;
3940  while (search_start <= data_len)
3941  {
3942  int regexec_result;
3943 
3945 
3946  regexec_result = pg_regexec(re,
3947  data,
3948  data_len,
3949  search_start,
3950  NULL, /* no details */
3952  pmatch,
3953  0);
3954 
3955  if (regexec_result == REG_NOMATCH)
3956  break;
3957 
3958  if (regexec_result != REG_OKAY)
3959  {
3960  char errMsg[100];
3961 
3963  pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
3964  ereport(ERROR,
3965  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
3966  errmsg("regular expression failed: %s", errMsg)));
3967  }
3968 
3969  /*
3970  * Copy the text to the left of the match position. Note we are given
3971  * character not byte indexes.
3972  */
3973  if (pmatch[0].rm_so - data_pos > 0)
3974  {
3975  int chunk_len;
3976 
3977  chunk_len = charlen_to_bytelen(start_ptr,
3978  pmatch[0].rm_so - data_pos);
3979  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
3980 
3981  /*
3982  * Advance start_ptr over that text, to avoid multiple rescans of
3983  * it if the replace_text contains multiple back-references.
3984  */
3985  start_ptr += chunk_len;
3986  data_pos = pmatch[0].rm_so;
3987  }
3988 
3989  /*
3990  * Copy the replace_text. Process back references when the
3991  * replace_text has escape characters.
3992  */
3993  if (have_escape)
3994  appendStringInfoRegexpSubstr(&buf, replace_text, pmatch,
3995  start_ptr, data_pos);
3996  else
3997  appendStringInfoText(&buf, replace_text);
3998 
3999  /* Advance start_ptr and data_pos over the matched text. */
4000  start_ptr += charlen_to_bytelen(start_ptr,
4001  pmatch[0].rm_eo - data_pos);
4002  data_pos = pmatch[0].rm_eo;
4003 
4004  /*
4005  * When global option is off, replace the first instance only.
4006  */
4007  if (!glob)
4008  break;
4009 
4010  /*
4011  * Advance search position. Normally we start the next search at the
4012  * end of the previous match; but if the match was of zero length, we
4013  * have to advance by one character, or we'd just find the same match
4014  * again.
4015  */
4016  search_start = data_pos;
4017  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4018  search_start++;
4019  }
4020 
4021  /*
4022  * Copy the text to the right of the last match.
4023  */
4024  if (data_pos < data_len)
4025  {
4026  int chunk_len;
4027 
4028  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4029  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4030  }
4031 
4032  ret_text = cstring_to_text_with_len(buf.data, buf.len);
4033  pfree(buf.data);
4034  pfree(data);
4035 
4036  return ret_text;
4037 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
regoff_t rm_so
Definition: regex.h:85
int errcode(int sqlerrcode)
Definition: elog.c:575
regoff_t rm_eo
Definition: regex.h:86
void pfree(void *pointer)
Definition: mcxt.c:936
#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:3773
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:736
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3676
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
#define ereport(elevel, rest)
Definition: elog.h:122
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define REGEXP_REPLACE_BACKREF_CNT
Definition: varlena.c:3900
#define VARSIZE_ANY(PTR)
Definition: postgres.h:334
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:723
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:3806
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:340
void * palloc(Size size)
Definition: mcxt.c:835
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define REG_NOMATCH
Definition: regex.h:138
Definition: c.h:497
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:98
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:208
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 5510 of file varlena.c.

Referenced by varstr_levenshtein().

5511 {
5512  while (len > 0)
5513  {
5514  len--;
5515  if (s1[len] != s2[len])
5516  return false;
5517  }
5518  return true;
5519 }
char * s1
char * s2

◆ split_text()

Datum split_text ( PG_FUNCTION_ARGS  )

Definition at line 4046 of file varlena.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, TextPositionState::len1, TextPositionState::len2, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, PointerGetDatum, text_position_cleanup(), text_position_next(), text_position_setup(), and text_substring().

4047 {
4048  text *inputstring = PG_GETARG_TEXT_PP(0);
4049  text *fldsep = PG_GETARG_TEXT_PP(1);
4050  int fldnum = PG_GETARG_INT32(2);
4051  int inputstring_len;
4052  int fldsep_len;
4054  int start_posn;
4055  int end_posn;
4056  text *result_text;
4057 
4058  /* field number is 1 based */
4059  if (fldnum < 1)
4060  ereport(ERROR,
4061  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4062  errmsg("field position must be greater than zero")));
4063 
4064  text_position_setup(inputstring, fldsep, &state);
4065 
4066  /*
4067  * Note: we check the converted string length, not the original, because
4068  * they could be different if the input contained invalid encoding.
4069  */
4070  inputstring_len = state.len1;
4071  fldsep_len = state.len2;
4072 
4073  /* return empty string for empty input string */
4074  if (inputstring_len < 1)
4075  {
4076  text_position_cleanup(&state);
4078  }
4079 
4080  /* empty field separator */
4081  if (fldsep_len < 1)
4082  {
4083  text_position_cleanup(&state);
4084  /* if first field, return input string, else empty string */
4085  if (fldnum == 1)
4086  PG_RETURN_TEXT_P(inputstring);
4087  else
4089  }
4090 
4091  /* identify bounds of first field */
4092  start_posn = 1;
4093  end_posn = text_position_next(1, &state);
4094 
4095  /* special case if fldsep not found at all */
4096  if (end_posn == 0)
4097  {
4098  text_position_cleanup(&state);
4099  /* if field 1 requested, return input string, else empty string */
4100  if (fldnum == 1)
4101  PG_RETURN_TEXT_P(inputstring);
4102  else
4104  }
4105 
4106  while (end_posn > 0 && --fldnum > 0)
4107  {
4108  /* identify bounds of next field */
4109  start_posn = end_posn + fldsep_len;
4110  end_posn = text_position_next(start_posn, &state);
4111  }
4112 
4113  text_position_cleanup(&state);
4114 
4115  if (fldnum > 0)
4116  {
4117  /* N'th field separator not found */
4118  /* if last field requested, return it, else empty string */
4119  if (fldnum == 1)
4120  result_text = text_substring(PointerGetDatum(inputstring),
4121  start_posn,
4122  -1,
4123  true);
4124  else
4125  result_text = cstring_to_text("");
4126  }
4127  else
4128  {
4129  /* non-last field requested */
4130  result_text = text_substring(PointerGetDatum(inputstring),
4131  start_posn,
4132  end_posn - start_posn,
4133  false);
4134  }
4135 
4136  PG_RETURN_TEXT_P(result_text);
4137 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PointerGetDatum(X)
Definition: postgres.h:562
static void text_position_setup(text *t1, text *t2, TextPositionState *state)
Definition: varlena.c:1119
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define ERROR
Definition: elog.h:43
static int text_position_next(int start_pos, TextPositionState *state)
Definition: varlena.c:1231
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:815
#define ereport(elevel, rest)
Definition: elog.h:122
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1365
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
text * cstring_to_text(const char *s)
Definition: varlena.c:150
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ SplitDirectoriesString()

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

Definition at line 3390 of file varlena.c.

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

Referenced by load_libraries(), and PostmasterMain().

3392 {
3393  char *nextp = rawstring;
3394  bool done = false;
3395 
3396  *namelist = NIL;
3397 
3398  while (scanner_isspace(*nextp))
3399  nextp++; /* skip leading whitespace */
3400 
3401  if (*nextp == '\0')
3402  return true; /* allow empty string */
3403 
3404  /* At the top of the loop, we are at start of a new directory. */
3405  do
3406  {
3407  char *curname;
3408  char *endp;
3409 
3410  if (*nextp == '"')
3411  {
3412  /* Quoted name --- collapse quote-quote pairs */
3413  curname = nextp + 1;
3414  for (;;)
3415  {
3416  endp = strchr(nextp + 1, '"');
3417  if (endp == NULL)
3418  return false; /* mismatched quotes */
3419  if (endp[1] != '"')
3420  break; /* found end of quoted name */
3421  /* Collapse adjacent quotes into one quote, and look again */
3422  memmove(endp, endp + 1, strlen(endp));
3423  nextp = endp;
3424  }
3425  /* endp now points at the terminating quote */
3426  nextp = endp + 1;
3427  }
3428  else
3429  {
3430  /* Unquoted name --- extends to separator or end of string */
3431  curname = endp = nextp;
3432  while (*nextp && *nextp != separator)
3433  {
3434  /* trailing whitespace should not be included in name */
3435  if (!scanner_isspace(*nextp))
3436  endp = nextp + 1;
3437  nextp++;
3438  }
3439  if (curname == endp)
3440  return false; /* empty unquoted name not allowed */
3441  }
3442 
3443  while (scanner_isspace(*nextp))
3444  nextp++; /* skip trailing whitespace */
3445 
3446  if (*nextp == separator)
3447  {
3448  nextp++;
3449  while (scanner_isspace(*nextp))
3450  nextp++; /* skip leading whitespace for next */
3451  /* we expect another name, so done remains false */
3452  }
3453  else if (*nextp == '\0')
3454  done = true;
3455  else
3456  return false; /* invalid syntax */
3457 
3458  /* Now safe to overwrite separator with a null */
3459  *endp = '\0';
3460 
3461  /* Truncate path if it's overlength */
3462  if (strlen(curname) >= MAXPGPATH)
3463  curname[MAXPGPATH - 1] = '\0';
3464 
3465  /*
3466  * Finished isolating current name --- add it to list
3467  */
3468  curname = pstrdup(curname);
3469  canonicalize_path(curname);
3470  *namelist = lappend(*namelist, curname);
3471 
3472  /* Loop back if we didn't reach end of string */
3473  } while (!done);
3474 
3475  return true;
3476 }
#define NIL
Definition: pg_list.h:69
char * pstrdup(const char *in)
Definition: mcxt.c:1063
void canonicalize_path(char *path)
Definition: path.c:254
#define MAXPGPATH
#define memmove(d, s, c)
Definition: c.h:1055
List * lappend(List *list, void *datum)
Definition: list.c:128
bool scanner_isspace(char ch)
Definition: scansup.c:221

◆ SplitIdentifierString()

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

Definition at line 3263 of file varlena.c.

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

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

3265 {
3266  char *nextp = rawstring;
3267  bool done = false;
3268 
3269  *namelist = NIL;
3270 
3271  while (scanner_isspace(*nextp))
3272  nextp++; /* skip leading whitespace */
3273 
3274  if (*nextp == '\0')
3275  return true; /* allow empty string */
3276 
3277  /* At the top of the loop, we are at start of a new identifier. */
3278  do
3279  {
3280  char *curname;
3281  char *endp;
3282 
3283  if (*nextp == '"')
3284  {
3285  /* Quoted name --- collapse quote-quote pairs, no downcasing */
3286  curname = nextp + 1;
3287  for (;;)
3288  {
3289  endp = strchr(nextp + 1, '"');
3290  if (endp == NULL)
3291  return false; /* mismatched quotes */
3292  if (endp[1] != '"')
3293  break; /* found end of quoted name */
3294  /* Collapse adjacent quotes into one quote, and look again */
3295  memmove(endp, endp + 1, strlen(endp));
3296  nextp = endp;
3297  }
3298  /* endp now points at the terminating quote */
3299  nextp = endp + 1;
3300  }
3301  else
3302  {
3303  /* Unquoted name --- extends to separator or whitespace */
3304  char *downname;
3305  int len;
3306 
3307  curname = nextp;
3308  while (*nextp && *nextp != separator &&
3309  !scanner_isspace(*nextp))
3310  nextp++;
3311  endp = nextp;
3312  if (curname == nextp)
3313  return false; /* empty unquoted name not allowed */
3314 
3315  /*
3316  * Downcase the identifier, using same code as main lexer does.
3317  *
3318  * XXX because we want to overwrite the input in-place, we cannot
3319  * support a downcasing transformation that increases the string
3320  * length. This is not a problem given the current implementation
3321  * of downcase_truncate_identifier, but we'll probably have to do
3322  * something about this someday.
3323  */
3324  len = endp - curname;
3325  downname = downcase_truncate_identifier(curname, len, false);
3326  Assert(strlen(downname) <= len);
3327  strncpy(curname, downname, len); /* strncpy is required here */
3328  pfree(downname);
3329  }
3330 
3331  while (scanner_isspace(*nextp))
3332  nextp++; /* skip trailing whitespace */
3333 
3334  if (*nextp == separator)
3335  {
3336  nextp++;
3337  while (scanner_isspace(*nextp))
3338  nextp++; /* skip leading whitespace for next */
3339  /* we expect another name, so done remains false */
3340  }
3341  else if (*nextp == '\0')
3342  done = true;
3343  else
3344  return false; /* invalid syntax */
3345 
3346  /* Now safe to overwrite separator with a null */
3347  *endp = '\0';
3348 
3349  /* Truncate name if it's overlength */
3350  truncate_identifier(curname, strlen(curname), false);
3351 
3352  /*
3353  * Finished isolating current name --- add it to list
3354  */
3355  *namelist = lappend(*namelist, curname);
3356 
3357  /* Loop back if we didn't reach end of string */
3358  } while (!done);
3359 
3360  return true;
3361 }
#define NIL
Definition: pg_list.h:69
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:131
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:187
void pfree(void *pointer)
Definition: mcxt.c:936
#define memmove(d, s, c)
Definition: c.h:1055
List * lappend(List *list, void *datum)
Definition: list.c:128
bool scanner_isspace(char ch)
Definition: scansup.c:221
#define Assert(condition)
Definition: c.h:680

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

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

4725 {
4726  StringInfo state;
4727 
4728  /* cannot be called directly because of internal-type argument */
4729  Assert(AggCheckCallContext(fcinfo, NULL));
4730 
4731  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
4732 
4733  if (state != NULL)
4735  else
4736  PG_RETURN_NULL();
4737 }
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define Assert(condition)
Definition: c.h:680
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4127
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 4698 of file varlena.c.

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

4699 {
4700  StringInfo state;
4701 
4702  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
4703 
4704  /* Append the value unless null. */
4705  if (!PG_ARGISNULL(1))
4706  {
4707  /* On the first time through, we ignore the delimiter. */
4708  if (state == NULL)
4709  state = makeStringAggState(fcinfo);
4710  else if (!PG_ARGISNULL(2))
4711  appendStringInfoText(state, PG_GETARG_TEXT_PP(2)); /* delimiter */
4712 
4713  appendStringInfoText(state, PG_GETARG_TEXT_PP(1)); /* value */
4714  }
4715 
4716  /*
4717  * The transition type for string_agg() is declared to be "internal",
4718  * which is a pass-by-value type the same size as a pointer.
4719  */
4720  PG_RETURN_POINTER(state);
4721 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:321
StringInfoData * StringInfo
Definition: stringinfo.h:43
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:241
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:3676
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:4674

◆ text_catenate()

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

Definition at line 695 of file varlena.c.

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

Referenced by text_overlay(), and textcat().

696 {
697  text *result;
698  int len1,
699  len2,
700  len;
701  char *ptr;
702 
703  len1 = VARSIZE_ANY_EXHDR(t1);
704  len2 = VARSIZE_ANY_EXHDR(t2);
705 
706  /* paranoia ... probably should throw error instead? */
707  if (len1 < 0)
708  len1 = 0;
709  if (len2 < 0)
710  len2 = 0;
711 
712  len = len1 + len2 + VARHDRSZ;
713  result = (text *) palloc(len);
714 
715  /* Set size of result string... */
716  SET_VARSIZE(result, len);
717 
718  /* Fill data field of result string... */
719  ptr = VARDATA(result);
720  if (len1 > 0)
721  memcpy(ptr, VARDATA_ANY(t1), len1);
722  if (len2 > 0)
723  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
724 
725  return result;
726 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void * palloc(Size size)
Definition: mcxt.c:835
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ text_cmp()

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

Definition at line 1617 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(), and text_smaller().

1618 {
1619  char *a1p,
1620  *a2p;
1621  int len1,
1622  len2;
1623 
1624  a1p = VARDATA_ANY(arg1);
1625  a2p = VARDATA_ANY(arg2);
1626 
1627  len1 = VARSIZE_ANY_EXHDR(arg1);
1628  len2 = VARSIZE_ANY_EXHDR(arg2);
1629 
1630  return varstr_cmp(a1p, len1, a2p, len2, collid);
1631 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1382
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 4864 of file varlena.c.

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

4865 {
4866  text *result;
4867 
4868  result = concat_internal("", 0, fcinfo);
4869  if (result == NULL)
4870  PG_RETURN_NULL();
4871  PG_RETURN_TEXT_P(result);
4872 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:4784
Definition: c.h:497
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 4879 of file varlena.c.

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

4880 {
4881  char *sep;
4882  text *result;
4883 
4884  /* return NULL when separator is NULL */
4885  if (PG_ARGISNULL(0))
4886  PG_RETURN_NULL();
4888 
4889  result = concat_internal(sep, 1, fcinfo);
4890  if (result == NULL)
4891  PG_RETURN_NULL();
4892  PG_RETURN_TEXT_P(result);
4893 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:4784
char * text_to_cstring(const text *t)
Definition: varlena.c:183
Definition: c.h:497
#define PG_RETURN_NULL()
Definition: fmgr.h:305

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

Definition at line 4996 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(), INT2OID, INT4OID, InvalidOid, StringInfoData::len, OidIsValid, OutputFunctionCall(), pfree(), PG_ARGISNULL, pg_atoi(), PG_GETARG_ARRAYTYPE_P, PG_GETARG_DATUM, PG_GETARG_TEXT_PP, PG_NARGS, PG_RETURN_NULL, PG_RETURN_TEXT_P, generate_unaccent_rules::str, text_format_parse_format(), text_format_string_conversion(), value, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by text_format_nv().

4997 {
4998  text *fmt;
5000  const char *cp;
5001  const char *start_ptr;
5002  const char *end_ptr;
5003  text *result;
5004  int arg;
5005  bool funcvariadic;
5006  int nargs;
5007  Datum *elements = NULL;
5008  bool *nulls = NULL;
5009  Oid element_type = InvalidOid;
5010  Oid prev_type = InvalidOid;
5011  Oid prev_width_type = InvalidOid;
5012  FmgrInfo typoutputfinfo;
5013  FmgrInfo typoutputinfo_width;
5014 
5015  /* When format string is null, immediately return null */
5016  if (PG_ARGISNULL(0))
5017  PG_RETURN_NULL();
5018 
5019  /* If argument is marked VARIADIC, expand array into elements */
5020  if (get_fn_expr_variadic(fcinfo->flinfo))
5021  {
5022  ArrayType *arr;
5023  int16 elmlen;
5024  bool elmbyval;
5025  char elmalign;
5026  int nitems;
5027 
5028  /* Should have just the one argument */
5029  Assert(PG_NARGS() == 2);
5030 
5031  /* If argument is NULL, we treat it as zero-length array */
5032  if (PG_ARGISNULL(1))
5033  nitems = 0;
5034  else
5035  {
5036  /*
5037  * Non-null argument had better be an array. We assume that any
5038  * call context that could let get_fn_expr_variadic return true
5039  * will have checked that a VARIADIC-labeled parameter actually is
5040  * an array. So it should be okay to just Assert that it's an
5041  * array rather than doing a full-fledged error check.
5042  */
5044 
5045  /* OK, safe to fetch the array value */
5046  arr = PG_GETARG_ARRAYTYPE_P(1);
5047 
5048  /* Get info about array element type */
5049  element_type = ARR_ELEMTYPE(arr);
5050  get_typlenbyvalalign(element_type,
5051  &elmlen, &elmbyval, &elmalign);
5052 
5053  /* Extract all array elements */
5054  deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
5055  &elements, &nulls, &nitems);
5056  }
5057 
5058  nargs = nitems + 1;
5059  funcvariadic = true;
5060  }
5061  else
5062  {
5063  /* Non-variadic case, we'll process the arguments individually */
5064  nargs = PG_NARGS();
5065  funcvariadic = false;
5066  }
5067 
5068  /* Setup for main loop. */
5069  fmt = PG_GETARG_TEXT_PP(0);
5070  start_ptr = VARDATA_ANY(fmt);
5071  end_ptr = start_ptr + VARSIZE_ANY_EXHDR(fmt);
5072  initStringInfo(&str);
5073  arg = 1; /* next argument position to print */
5074 
5075  /* Scan format string, looking for conversion specifiers. */
5076  for (cp = start_ptr; cp < end_ptr; cp++)
5077  {
5078  int argpos;
5079  int widthpos;
5080  int flags;
5081  int width;
5082  Datum value;
5083  bool isNull;
5084  Oid typid;
5085 
5086  /*
5087  * If it's not the start of a conversion specifier, just copy it to
5088  * the output buffer.
5089  */
5090  if (*cp != '%')
5091  {
5092  appendStringInfoCharMacro(&str, *cp);
5093  continue;
5094  }
5095 
5096  ADVANCE_PARSE_POINTER(cp, end_ptr);
5097 
5098  /* Easy case: %% outputs a single % */
5099  if (*cp == '%')
5100  {
5101  appendStringInfoCharMacro(&str, *cp);
5102  continue;
5103  }
5104 
5105  /* Parse the optional portions of the format specifier */
5106  cp = text_format_parse_format(cp, end_ptr,
5107  &argpos, &widthpos,
5108  &flags, &width);
5109 
5110  /*
5111  * Next we should see the main conversion specifier. Whether or not
5112  * an argument position was present, it's known that at least one
5113  * character remains in the string at this point. Experience suggests
5114  * that it's worth checking that that character is one of the expected
5115  * ones before we try to fetch arguments, so as to produce the least
5116  * confusing response to a mis-formatted specifier.
5117  */
5118  if (strchr("sIL", *cp) == NULL)
5119  ereport(ERROR,
5120  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5121  errmsg("unrecognized format() type specifier \"%c\"",
5122  *cp),
5123  errhint("For a single \"%%\" use \"%%%%\".")));
5124 
5125  /* If indirect width was specified, get its value */
5126  if (widthpos >= 0)
5127  {
5128  /* Collect the specified or next argument position */
5129  if (widthpos > 0)
5130  arg = widthpos;
5131  if (arg >= nargs)
5132  ereport(ERROR,
5133  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5134  errmsg("too few arguments for format()")));
5135 
5136  /* Get the value and type of the selected argument */
5137  if (!funcvariadic)
5138  {
5139  value = PG_GETARG_DATUM(arg);
5140  isNull = PG_ARGISNULL(arg);
5141  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5142  }
5143  else
5144  {
5145  value = elements[arg - 1];
5146  isNull = nulls[arg - 1];
5147  typid = element_type;
5148  }
5149  if (!OidIsValid(typid))
5150  elog(ERROR, "could not determine data type of format() input");
5151 
5152  arg++;
5153 
5154  /* We can treat NULL width the same as zero */
5155  if (isNull)
5156  width = 0;
5157  else if (typid == INT4OID)
5158  width = DatumGetInt32(value);
5159  else if (typid == INT2OID)
5160  width = DatumGetInt16(value);
5161  else
5162  {
5163  /* For less-usual datatypes, convert to text then to int */
5164  char *str;
5165 
5166  if (typid != prev_width_type)
5167  {
5168  Oid typoutputfunc;
5169  bool typIsVarlena;
5170 
5171  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5172  fmgr_info(typoutputfunc, &typoutputinfo_width);
5173  prev_width_type = typid;
5174  }
5175 
5176  str = OutputFunctionCall(&typoutputinfo_width, value);
5177 
5178  /* pg_atoi will complain about bad data or overflow */
5179  width = pg_atoi(str, sizeof(int), '\0');
5180 
5181  pfree(str);
5182  }
5183  }
5184 
5185  /* Collect the specified or next argument position */
5186  if (argpos > 0)
5187  arg = argpos;
5188  if (arg >= nargs)
5189  ereport(ERROR,
5190  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5191  errmsg("too few arguments for format()")));
5192 
5193  /* Get the value and type of the selected argument */
5194  if (!funcvariadic)
5195  {
5196  value = PG_GETARG_DATUM(arg);
5197  isNull = PG_ARGISNULL(arg);
5198  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5199  }
5200  else
5201  {
5202  value = elements[arg - 1];
5203  isNull = nulls[arg - 1];
5204  typid = element_type;
5205  }
5206  if (!OidIsValid(typid))
5207  elog(ERROR, "could not determine data type of format() input");
5208 
5209  arg++;
5210 
5211  /*
5212  * Get the appropriate typOutput function, reusing previous one if
5213  * same type as previous argument. That's particularly useful in the
5214  * variadic-array case, but often saves work even for ordinary calls.
5215  */
5216  if (typid != prev_type)
5217  {
5218  Oid typoutputfunc;
5219  bool typIsVarlena;
5220 
5221  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5222  fmgr_info(typoutputfunc, &typoutputfinfo);
5223  prev_type = typid;
5224  }
5225 
5226  /*
5227  * And now we can format the value.
5228  */
5229  switch (*cp)
5230  {
5231  case 's':
5232  case 'I':
5233  case 'L':
5234  text_format_string_conversion(&str, *cp, &typoutputfinfo,
5235  value, isNull,
5236  flags, width);
5237  break;
5238  default:
5239  /* should not get here, because of previous check */
5240  ereport(ERROR,
5241  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5242  errmsg("unrecognized format() type specifier \"%c\"",
5243  *cp),
5244  errhint("For a single \"%%\" use \"%%%%\".")));
5245  break;
5246  }
5247  }
5248 
5249  /* Don't need deconstruct_array results anymore. */
5250  if (elements != NULL)
5251  pfree(elements);
5252  if (nulls != NULL)
5253  pfree(nulls);
5254 
5255  /* Generate results. */
5256  result = cstring_to_text_with_len(str.data, str.len);
5257  pfree(str.data);
5258 
5259  PG_RETURN_TEXT_P(result);
5260 }
signed short int16
Definition: c.h:293
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:4983
Definition: fmgr.h:56
int errhint(const char *fmt,...)
Definition: elog.c:987
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2665
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define DatumGetInt32(X)
Definition: postgres.h:478
static void text_format_string_conversion(StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
Definition: varlena.c:5399
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2040
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define INT4OID
Definition: pg_type.h:316
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2038
int errcode(int sqlerrcode)
Definition: elog.c:575
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:586
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1662
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:248
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:127
void pfree(void *pointer)
Definition: mcxt.c:936
#define ERROR
Definition: elog.h:43
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1904
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:122
static struct @121 value
#define INT2OID
Definition: pg_type.h:308
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
#define DatumGetInt16(X)
Definition: postgres.h:450
#define ereport(elevel, rest)
Definition: elog.h:122
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
uintptr_t Datum
Definition: postgres.h:372
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
#define Assert(condition)
Definition: c.h:680
#define PG_NARGS()
Definition: fmgr.h:168
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3449
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2590
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * arg
Definition: c.h:497
#define elog
Definition: elog.h:219
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:5322
#define ARR_ELEMTYPE(a)
Definition: array.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:305
int32 pg_atoi(const char *s, int size, int c)
Definition: numutils.c:37

◆ text_format_append_string()

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

Definition at line 5448 of file varlena.c.

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

Referenced by text_format_string_conversion().

5450 {
5451  bool align_to_left = false;
5452  int len;
5453 
5454  /* fast path for typical easy case */
5455  if (width == 0)
5456  {
5458  return;
5459  }
5460 
5461  if (width < 0)
5462  {
5463  /* Negative width: implicit '-' flag, then take absolute value */
5464  align_to_left = true;
5465  /* -INT_MIN is undefined */
5466  if (width <= INT_MIN)
5467  ereport(ERROR,
5468  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5469  errmsg("number is out of range")));
5470  width = -width;
5471  }
5472  else if (flags & TEXT_FORMAT_FLAG_MINUS)
5473  align_to_left = true;
5474 
5475  len = pg_mbstrlen(str);
5476  if (align_to_left)
5477  {
5478  /* left justify */
5480  if (len < width)
5481  appendStringInfoSpaces(buf, width - len);
5482  }
5483  else
5484  {
5485  /* right justify */
5486  if (len < width)
5487  appendStringInfoSpaces(buf, width - len);
5489  }
5490 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
#define ereport(elevel, rest)
Definition: elog.h:122
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:187
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:774
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:4981

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 5500 of file varlena.c.

References text_format().

5501 {
5502  return text_format(fcinfo);
5503 }
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:4996

◆ text_format_parse_digits()

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

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

5274 {
5275  bool found = false;
5276  const char *cp = *ptr;
5277  int val = 0;
5278 
5279  while (*cp >= '0' && *cp <= '9')
5280  {
5281  int8 digit = (*cp - '0');
5282 
5283  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5284  unlikely(pg_add_s32_overflow(val, digit, &val)))
5285  ereport(ERROR,
5286  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5287  errmsg("number is out of range")));
5288  ADVANCE_PARSE_POINTER(cp, end_ptr);
5289  found = true;
5290  }
5291 
5292  *ptr = cp;
5293  *value = val;
5294 
5295  return found;
5296 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:4983
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:129
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
static struct @121 value
#define ereport(elevel, rest)
Definition: elog.h:122
signed char int8
Definition: c.h:292
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:89
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define unlikely(x)
Definition: c.h:200
long val
Definition: informix.c:689

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

5325 {
5326  const char *cp = start_ptr;
5327  int n;
5328 
5329  /* set defaults for output parameters */
5330  *argpos = -1;
5331  *widthpos = -1;
5332  *flags = 0;
5333  *width = 0;
5334 
5335  /* try to identify first number */
5336  if (text_format_parse_digits(&cp, end_ptr, &n))
5337  {
5338  if (*cp != '$')
5339  {
5340  /* Must be just a width and a type, so we're done */
5341  *width = n;
5342  return cp;
5343  }
5344  /* The number was argument position */
5345  *argpos = n;
5346  /* Explicit 0 for argument index is immediately refused */
5347  if (n == 0)
5348  ereport(ERROR,
5349  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5350  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5351  ADVANCE_PARSE_POINTER(cp, end_ptr);
5352  }
5353 
5354  /* Handle flags (only minus is supported now) */
5355  while (*cp == '-')
5356  {
5357  *flags |= TEXT_FORMAT_FLAG_MINUS;
5358  ADVANCE_PARSE_POINTER(cp, end_ptr);
5359  }
5360 
5361  if (*cp == '*')
5362  {
5363  /* Handle indirect width */
5364  ADVANCE_PARSE_POINTER(cp, end_ptr);
5365  if (text_format_parse_digits(&cp, end_ptr, &n))
5366  {
5367  /* number in this position must be closed by $ */
5368  if (*cp != '$')
5369  ereport(ERROR,
5370  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5371  errmsg("width argument position must be ended by \"$\"")));
5372  /* The number was width argument position */
5373  *widthpos = n;
5374  /* Explicit 0 for argument index is immediately refused */
5375  if (n == 0)
5376  ereport(ERROR,
5377  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5378  errmsg("format specifies argument 0, but arguments are numbered from 1")));
5379  ADVANCE_PARSE_POINTER(cp, end_ptr);
5380  }
5381  else
5382  *widthpos = 0; /* width's argument position is unspecified */
5383  }
5384  else
5385  {
5386  /* Check for direct width specification */
5387  if (text_format_parse_digits(&cp, end_ptr, &n))
5388  *width = n;
5389  }
5390 
5391  /* cp should now be pointing at type character */
5392  return cp;
5393 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:4983
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:5273
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:4981

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

5403 {
5404  char *str;
5405 
5406  /* Handle NULL arguments before trying to stringify the value. */
5407  if (isNull)
5408  {
5409  if (conversion == 's')
5410  text_format_append_string(buf, "", flags, width);
5411  else if (conversion == 'L')
5412  text_format_append_string(buf, "NULL", flags, width);
5413  else if (conversion == 'I')
5414  ereport(ERROR,
5415  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
5416  errmsg("null values cannot be formatted as an SQL identifier")));
5417  return;
5418  }
5419 
5420  /* Stringify. */
5421  str = OutputFunctionCall(typOutputInfo, value);
5422 
5423  /* Escape. */
5424  if (conversion == 'I')
5425  {
5426  /* quote_identifier may or may not allocate a new string. */
5427  text_format_append_string(buf, quote_identifier(str), flags, width);
5428  }
5429  else if (conversion == 'L')
5430  {
5431  char *qstr = quote_literal_cstr(str);
5432 
5433  text_format_append_string(buf, qstr, flags, width);
5434  /* quote_literal_cstr() always allocates a new string */
5435  pfree(qstr);
5436  }
5437  else
5438  text_format_append_string(buf, str, flags, width);
5439 
5440  /* Cleanup. */
5441  pfree(str);
5442 }
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:102
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10412
int errcode(int sqlerrcode)
Definition: elog.c:575
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:5448
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1662
void pfree(void *pointer)
Definition: mcxt.c:936
#define ERROR
Definition: elog.h:43
static struct @121 value
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

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

1752 {
1753  text *arg1 = PG_GETARG_TEXT_PP(0);
1754  text *arg2 = PG_GETARG_TEXT_PP(1);
1755  bool result;
1756 
1757  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1758 
1759  PG_FREE_IF_COPY(arg1, 0);
1760  PG_FREE_IF_COPY(arg2, 1);
1761 
1762  PG_RETURN_BOOL(result);
1763 }
#define PG_GET_COLLATION()
Definition: fmgr.h:163
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

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

1737 {
1738  text *arg1 = PG_GETARG_TEXT_PP(0);
1739  text *arg2 = PG_GETARG_TEXT_PP(1);
1740  bool result;
1741 
1742  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1743 
1744  PG_FREE_IF_COPY(arg1, 0);
1745  PG_FREE_IF_COPY(arg2, 1);
1746 
1747  PG_RETURN_BOOL(result);
1748 }
#define PG_GET_COLLATION()
Definition: fmgr.h:163
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_isequal()

static bool text_isequal ( text txt1,
text txt2 
)
static

Definition at line 4143 of file varlena.c.

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

Referenced by text_to_array_internal().

4144 {
4146  PointerGetDatum(txt1),
4147  PointerGetDatum(txt2)));
4148 }
#define PointerGetDatum(X)
Definition: postgres.h:562
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1642
#define DatumGetBool(X)
Definition: postgres.h:399
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587

◆ text_larger()

Datum text_larger ( PG_FUNCTION_ARGS  )

Definition at line 2591 of file varlena.c.

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

2592 {
2593  text *arg1 = PG_GETARG_TEXT_PP(0);
2594  text *arg2 = PG_GETARG_TEXT_PP(1);
2595  text *result;
2596 
2597  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2598 
2599  PG_RETURN_TEXT_P(result);
2600 }
#define PG_GET_COLLATION()
Definition: fmgr.h:163
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
Definition: c.h:497

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

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

1722 {
1723  text *arg1 = PG_GETARG_TEXT_PP(0);
1724  text *arg2 = PG_GETARG_TEXT_PP(1);
1725  bool result;
1726 
1727  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1728 
1729  PG_FREE_IF_COPY(arg1, 0);
1730  PG_FREE_IF_COPY(arg2, 1);
1731 
1732  PG_RETURN_BOOL(result);
1733 }
#define PG_GET_COLLATION()
Definition: fmgr.h:163
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

Definition at line 4900 of file varlena.c.

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

4901 {
4902  text *str = PG_GETARG_TEXT_PP(0);
4903  const char *p = VARDATA_ANY(str);
4904  int len = VARSIZE_ANY_EXHDR(str);
4905  int n = PG_GETARG_INT32(1);
4906  int rlen;
4907 
4908  if (n < 0)
4909  n = pg_mbstrlen_with_len(p, len) + n;
4910  rlen = pg_mbcharcliplen(p, len, n);
4911 
4913 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:862
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497

◆ text_length()

static int32 text_length ( Datum  str)
static

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

642 {
643  /* fastpath when max encoding length is one */
646  else
647  {
648  text *t = DatumGetTextPP(str);
649 
651  VARSIZE_ANY_EXHDR(t)));
652  }
653 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define VARHDRSZ
Definition: c.h:503
#define DatumGetTextPP(X)
Definition: fmgr.h:256
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
Size toast_raw_datum_size(Datum value)
Definition: tuptoaster.c:353
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497

◆ text_lt()

Datum text_lt ( PG_FUNCTION_ARGS  )

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

1707 {
1708  text *arg1 = PG_GETARG_TEXT_PP(0);
1709  text *arg2 = PG_GETARG_TEXT_PP(1);
1710  bool result;
1711 
1712  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
1713 
1714  PG_FREE_IF_COPY(arg1, 0);
1715  PG_FREE_IF_COPY(arg2, 1);
1716 
1717  PG_RETURN_BOOL(result);
1718 }
#define PG_GET_COLLATION()
Definition: fmgr.h:163
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_name()

Datum text_name ( PG_FUNCTION_ARGS  )

Definition at line 3165 of file varlena.c.

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

3166 {
3167  text *s = PG_GETARG_TEXT_PP(0);
3168  Name result;
3169  int len;
3170 
3171  len = VARSIZE_ANY_EXHDR(s);
3172 
3173  /* Truncate oversize input */
3174  if (len >= NAMEDATALEN)
3175  len = pg_mbcliplen(VARDATA_ANY(s), len, NAMEDATALEN - 1);
3176 
3177  /* We use palloc0 here to ensure result is zero-padded */
3178  result = (Name) palloc0(NAMEDATALEN);
3179  memcpy(NameStr(*result), VARDATA_ANY(s), len);
3180 
3181  PG_RETURN_NAME(result);
3182 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
#define NAMEDATALEN
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:820
Definition: c.h:551
void * palloc0(Size size)
Definition: mcxt.c:864
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
#define NameStr(name)
Definition: c.h:557
Definition: c.h:497
NameData * Name
Definition: c.h:555
#define PG_RETURN_NAME(x)
Definition: fmgr.h:323

◆ text_overlay()

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

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

1036 {
1037  text *result;
1038  text *s1;
1039  text *s2;
1040  int sp_pl_sl;
1041 
1042  /*
1043  * Check for possible integer-overflow cases. For negative sp, throw a
1044  * "substring length" error because that's what should be expected
1045  * according to the spec's definition of OVERLAY().
1046  */
1047  if (sp <= 0)
1048  ereport(ERROR,
1049  (errcode(ERRCODE_SUBSTRING_ERROR),
1050  errmsg("negative substring length not allowed")));
1051  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
1052  ereport(ERROR,
1053  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1054  errmsg("integer out of range")));
1055 
1056  s1 = text_substring(PointerGetDatum(t1), 1, sp - 1, false);
1057  s2 = text_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
1058  result = text_catenate(s1, t2);
1059  result = text_catenate(result, s2);
1060 
1061  return result;
1062 }
#define PointerGetDatum(X)
Definition: postgres.h:562
int errcode(int sqlerrcode)
Definition: elog.c:575
#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:815
static text * text_catenate(text *t1, text *t2)
Definition: varlena.c:695
#define ereport(elevel, rest)
Definition: elog.h:122
char * s2
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:89
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:497

◆ text_pattern_ge()

Datum text_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 2678 of file varlena.c.

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

2679 {
2680  text *arg1 = PG_GETARG_TEXT_PP(0);
2681  text *arg2 = PG_GETARG_TEXT_PP(1);
2682  int result;
2683 
2684  result = internal_text_pattern_compare(arg1, arg2);
2685 
2686  PG_FREE_IF_COPY(arg1, 0);
2687  PG_FREE_IF_COPY(arg2, 1);
2688 
2689  PG_RETURN_BOOL(result >= 0);
2690 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2624
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_pattern_gt()

Datum text_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 2694 of file varlena.c.

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

2695 {
2696  text *arg1 = PG_GETARG_TEXT_PP(0);
2697  text *arg2 = PG_GETARG_TEXT_PP(1);
2698  int result;
2699 
2700  result = internal_text_pattern_compare(arg1, arg2);
2701 
2702  PG_FREE_IF_COPY(arg1, 0);
2703  PG_FREE_IF_COPY(arg2, 1);
2704 
2705  PG_RETURN_BOOL(result > 0);
2706 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2624
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_pattern_le()

Datum text_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 2662 of file varlena.c.

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

2663 {
2664  text *arg1 = PG_GETARG_TEXT_PP(0);
2665  text *arg2 = PG_GETARG_TEXT_PP(1);
2666  int result;
2667 
2668  result = internal_text_pattern_compare(arg1, arg2);
2669 
2670  PG_FREE_IF_COPY(arg1, 0);
2671  PG_FREE_IF_COPY(arg2, 1);
2672 
2673  PG_RETURN_BOOL(result <= 0);
2674 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2624
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_pattern_lt()

Datum text_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 2646 of file varlena.c.

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

2647 {
2648  text *arg1 = PG_GETARG_TEXT_PP(0);
2649  text *arg2 = PG_GETARG_TEXT_PP(1);
2650  int result;
2651 
2652  result = internal_text_pattern_compare(arg1, arg2);
2653 
2654  PG_FREE_IF_COPY(arg1, 0);
2655  PG_FREE_IF_COPY(arg2, 1);
2656 
2657  PG_RETURN_BOOL(result < 0);
2658 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2624
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:225
Definition: c.h:497

◆ text_position()

static int text_position ( text t1,
text t2 
)
static

Definition at line 1095 of file varlena.c.

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

Referenced by textpos().

1096 {
1098  int result;
1099 
1100  text_position_setup(t1, t2, &state);
1101  result = text_position_next(1, &state);
1102  text_position_cleanup(&state);
1103  return result;
1104 }
static void text_position_setup(text *t1, text *t2, TextPositionState *state)
Definition: varlena.c:1119
static int text_position_next(int start_pos, TextPositionState *state)
Definition: varlena.c:1231
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1365

◆ text_position_cleanup()

static void text_position_cleanup ( TextPositionState state)
static

Definition at line 1365 of file varlena.c.

References pfree(), TextPositionState::use_wchar, TextPositionState::wstr1, and TextPositionState::wstr2.

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

1366 {
1367  if (state->use_wchar)
1368  {
1369  pfree(state->wstr1);
1370  pfree(state->wstr2);
1371  }
1372 }
pg_wchar * wstr2
Definition: varlena.c:53
void pfree(void *pointer)
Definition: mcxt.c:936
pg_wchar * wstr1
Definition: varlena.c:52

◆ text_position_next()

static int text_position_next ( int  start_pos,
TextPositionState state 
)
static

Definition at line 1231 of file varlena.c.

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

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

1232 {
1233  int haystack_len = state->len1;
1234  int needle_len = state->len2;
1235  int skiptablemask = state->skiptablemask;
1236 
1237  Assert(start_pos > 0); /* else caller error */
1238 
1239  if (needle_len <= 0)
1240  return start_pos; /* result for empty pattern */
1241 
1242  start_pos--; /* adjust for zero based arrays */
1243 
1244  /* Done if the needle can't possibly fit */
1245  if (haystack_len < start_pos + needle_len)
1246  return 0;
1247 
1248  if (!state->use_wchar)
1249  {
1250  /* simple case - single byte encoding */
1251  const char *haystack = state->str1;
1252  const char *needle = state->str2;
1253  const char *haystack_end = &haystack[haystack_len];
1254  const char *hptr;
1255 
1256  if (needle_len == 1)
1257  {
1258  /* No point in using B-M-H for a one-character needle */
1259  char nchar = *needle;
1260 
1261  hptr = &haystack[start_pos];
1262  while (hptr < haystack_end)
1263  {
1264  if (*hptr == nchar)
1265  return hptr - haystack + 1;
1266  hptr++;
1267  }
1268  }
1269  else
1270  {
1271  const char *needle_last = &needle[needle_len - 1];
1272 
1273  /* Start at startpos plus the length of the needle */
1274  hptr = &haystack[start_pos + needle_len - 1];
1275  while (hptr < haystack_end)
1276  {
1277  /* Match the needle scanning *backward* */
1278  const char *nptr;
1279  const char *p;
1280 
1281  nptr = needle_last;
1282  p = hptr;
1283  while (*nptr == *p)
1284  {
1285  /* Matched it all? If so, return 1-based position */
1286  if (nptr == needle)
1287  return p - haystack + 1;
1288  nptr--, p--;
1289  }
1290 
1291  /*
1292  * No match, so use the haystack char at hptr to decide how
1293  * far to advance. If the needle had any occurrence of that
1294  * character (or more precisely, one sharing the same
1295  * skiptable entry) before its last character, then we advance
1296  * far enough to align the last such needle character with
1297  * that haystack position. Otherwise we can advance by the
1298  * whole needle length.
1299  */
1300  hptr += state->skiptable[(unsigned char) *hptr & skiptablemask];
1301  }
1302  }
1303  }
1304  else
1305  {
1306  /* The multibyte char version. This works exactly the same way. */
1307  const pg_wchar *haystack = state->wstr1;
1308  const pg_wchar *needle = state->wstr2;
1309  const pg_wchar *haystack_end = &haystack[haystack_len];
1310  const pg_wchar *hptr;
1311 
1312  if (needle_len == 1)
1313  {
1314  /* No point in using B-M-H for a one-character needle */
1315  pg_wchar nchar = *needle;
1316 
1317  hptr = &haystack[start_pos];
1318  while (hptr < haystack_end)
1319  {
1320  if (*hptr == nchar)
1321  return hptr - haystack + 1;
1322  hptr++;
1323  }
1324  }
1325  else
1326  {
1327  const pg_wchar *needle_last = &needle[needle_len - 1];
1328 
1329  /* Start at startpos plus the length of the needle */
1330  hptr = &haystack[start_pos + needle_len - 1];
1331  while (hptr < haystack_end)
1332  {
1333  /* Match the needle scanning *backward* */
1334  const pg_wchar *nptr;
1335  const pg_wchar *p;
1336 
1337  nptr = needle_last;
1338  p = hptr;
1339  while (*nptr == *p)
1340  {
1341  /* Matched it all? If so, return 1-based position */
1342  if (nptr == needle)
1343  return p - haystack + 1;
1344  nptr--, p--;
1345  }
1346 
1347  /*
1348  * No match, so use the haystack char at hptr to decide how
1349  * far to advance. If the needle had any occurrence of that
1350  * character (or more precisely, one sharing the same
1351  * skiptable entry) before its last character, then we advance
1352  * far enough to align the last such needle character with
1353  * that haystack position. Otherwise we can advance by the
1354  * whole needle length.
1355  */
1356  hptr += state->skiptable[*hptr & skiptablemask];
1357  }
1358  }
1359  }
1360 
1361  return 0; /* not found */
1362 }
pg_wchar * wstr2
Definition: varlena.c:53
unsigned int pg_wchar
Definition: mbprint.c:31
int skiptable[256]
Definition: varlena.c:58
#define Assert(condition)
Definition: c.h:680
pg_wchar * wstr1
Definition: varlena.c:52

◆ text_position_setup()

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

Definition at line 1119 of file varlena.c.

References i, TextPositionState::len1, TextPositionState::len2, palloc(), pg_database_encoding_max_length(), pg_mb2wchar_with_len(), TextPositionState::skiptable, TextPositionState::skiptablemask, TextPositionState::str1, TextPositionState::str2, TextPositionState::use_wchar, VARDATA_ANY, VARSIZE_ANY_EXHDR, TextPositionState::wstr1, and TextPositionState::wstr2.

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

1120 {
1121  int len1 = VARSIZE_ANY_EXHDR(t1);
1122  int len2 = VARSIZE_ANY_EXHDR(t2);
1123 
1125  {
1126  /* simple case - single byte encoding */
1127  state->use_wchar = false;
1128  state->str1 = VARDATA_ANY(t1);
1129  state->str2 = VARDATA_ANY(t2);
1130  state->len1 = len1;
1131  state->len2 = len2;
1132  }
1133  else
1134  {
1135  /* not as simple - multibyte encoding */
1136  pg_wchar *p1,
1137  *p2;
1138 
1139  p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar));
1140  len1 = pg_mb2wchar_with_len(VARDATA_ANY(t1), p1, len1);
1141  p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar));
1142  len2 = pg_mb2wchar_with_len(VARDATA_ANY(t2), p2, len2);
1143 
1144  state->use_wchar = true;
1145  state->wstr1 = p1;
1146  state->wstr2 = p2;
1147  state->len1 = len1;
1148  state->len2 = len2;
1149  }
1150 
1151  /*
1152  * Prepare the skip table for Boyer-Moore-Horspool searching. In these
1153  * notes we use the terminology that the "haystack" is the string to be
1154  * searched (t1) and the "needle" is the pattern being sought (t2).
1155  *
1156  * If the needle is empty or bigger than the haystack then there is no
1157  * point in wasting cycles initializing the table. We also choose not to
1158  * use B-M-H for needles of length 1, since the skip table can't possibly
1159  * save anything in that case.
1160  */
1161  if (len1 >= len2 && len2 > 1)
1162  {
1163  int searchlength = len1 - len2;
1164  int skiptablemask;
1165  int last;
1166  int i;
1167 
1168  /*
1169  * First we must determine how much of the skip table to use. The
1170  * declaration of TextPositionState allows up to 256 elements, but for
1171  * short search problems we don't really want to have to initialize so
1172  * many elements --- it would take too long in comparison to the
1173  * actual search time. So we choose a useful skip table size based on
1174  * the haystack length minus the needle length. The closer the needle
1175  * length is to the haystack length the less useful skipping becomes.
1176  *
1177  * Note: since we use bit-masking to select table elements, the skip
1178  * table size MUST be a power of 2, and so the mask must be 2^N-1.
1179  */
1180  if (searchlength < 16)
1181  skiptablemask = 3;
1182  else if (searchlength < 64)
1183  skiptablemask = 7;
1184  else if (searchlength < 128)
1185  skiptablemask = 15;
1186  else if (searchlength < 512)
1187  skiptablemask = 31;
1188  else if (searchlength < 2048)
1189  skiptablemask = 63;
1190  else if (searchlength < 4096)
1191  skiptablemask = 127;
1192  else
1193  skiptablemask = 255;
1194  state->skiptablemask = skiptablemask;
1195 
1196  /*
1197  * Initialize the skip table. We set all elements to the needle
1198  * length, since this is the correct skip distance for any character
1199  * not found in the needle.
1200  */
1201  for (i = 0; i <= skiptablemask; i++)
1202  state->skiptable[i] = len2;
1203 
1204  /*
1205  * Now examine the needle. For each character except the last one,
1206  * set the corresponding table element to the appropriate skip
1207  * distance. Note that when two characters share the same skip table
1208  * entry, the one later in the needle must determine the skip
1209  * distance.
1210  */
1211  last = len2 - 1;
1212 
1213  if (!state->use_wchar)
1214  {
1215  const char *str2 = state->str2;
1216 
1217  for (i = 0; i < last; i++)
1218  state->skiptable[(unsigned char) str2[i] & skiptablemask] = last - i;
1219  }
1220  else
1221  {
1222  const pg_wchar *wstr2 = state->wstr2;
1223 
1224  for (i = 0; i < last; i++)
1225  state->skiptable[wstr2[i] & skiptablemask] = last - i;
1226  }
1227  }
1228 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
pg_wchar * wstr2
Definition: varlena.c:53
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
unsigned int pg_wchar
Definition: mbprint.c:31
int skiptable[256]
Definition: varlena.c:58
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:723
pg_wchar * wstr1
Definition: varlena.c:52
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void * palloc(Size size)
Definition: mcxt.c:835
int i

◆ text_reverse()

Datum text_reverse ( PG_FUNCTION_ARGS  )

Definition at line 4941 of file varlena.c.

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

4942 {
4943  text *str = PG_GETARG_TEXT_PP(0);
4944  const char *p = VARDATA_ANY(str);
4945  int len = VARSIZE_ANY_EXHDR(str);
4946  const char *endp = p + len;
4947  text *result;
4948  char *dst;
4949 
4950  result = palloc(len + VARHDRSZ);
4951  dst = (char *) VARDATA(result) + len;
4952  SET_VARSIZE(result, len + VARHDRSZ);
4953 
4955  {
4956  /* multibyte version */
4957  while (p < endp)
4958  {
4959  int sz;
4960 
4961  sz = pg_mblen(p);
4962  dst -= sz;
4963  memcpy(dst, p, sz);
4964  p += sz;
4965  }
4966  }
4967  else
4968  {
4969  /* single byte version */
4970  while (p < endp)
4971  *(--dst) = *p++;
4972  }
4973 
4974  PG_RETURN_TEXT_P(result);
4975 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define VARDATA(PTR)
Definition: postgres.h:303
#define VARHDRSZ
Definition: c.h:503
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
int pg_database_encoding_max_length(void)
Definition: wchar.c:1833
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
int pg_mblen(const char *mbstr)
Definition: mbutils.c:760
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
void * palloc(Size size)
Definition: mcxt.c:835
Definition: c.h:497
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:328

◆ text_right()

Datum text_right ( PG_FUNCTION_ARGS  )

Definition at line 4920 of file varlena.c.

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

4921 {
4922  text *str = PG_GETARG_TEXT_PP(0);
4923  const char *p = VARDATA_ANY(str);
4924  int len = VARSIZE_ANY_EXHDR(str);
4925  int n = PG_GETARG_INT32(1);
4926  int off;
4927 
4928  if (n < 0)
4929  n = -n;
4930  else
4931  n = pg_mbstrlen_with_len(p, len) - n;
4932  off = pg_mbcharcliplen(p, len, n);
4933 
4934  PG_RETURN_TEXT_P(cstring_to_text_with_len(p + off, len - off));
4935 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:862
#define VARDATA_ANY(PTR)
Definition: postgres.h:347
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:794
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:162
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:340
Definition: c.h:497

◆ text_smaller()

Datum text_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2603 of file varlena.c.

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

2604 {
2605  text *arg1 = PG_GETARG_TEXT_PP(0);
2606  text *arg2 = PG_GETARG_TEXT_PP(1);
2607  text *result;
2608 
2609  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0) ? arg1 : arg2);
2610 
2611  PG_RETURN_TEXT_P(result);
2612 }
#define PG_GET_COLLATION()
Definition: fmgr.h:163
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1617
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331
Definition: c.h:497

◆ text_substr()

Datum text_substr ( PG_FUNCTION_ARGS  )

Definition at line 782 of file varlena.c.

References PG_GETARG_DATUM, PG_GETARG_INT32, PG_RETURN_TEXT_P, and text_substring().

Referenced by build_regexp_match_result(), build_regexp_split_result(), and textregexsubstr().

783 {
785  PG_GETARG_INT32(1),
786  PG_GETARG_INT32(2),
787  false));
788 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:815
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331

◆ text_substr_no_len()

Datum text_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 796 of file varlena.c.

References PG_GETARG_DATUM, PG_GETARG_INT32, PG_RETURN_TEXT_P, and text_substring().

Referenced by build_regexp_split_result().

797 {
799  PG_GETARG_INT32(1),
800  -1, true));
801 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:815
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:331

◆ text_substring()

static text * text_substring ( Datum  str,
int32  start,
int32  length,
bool  length_not_specified 
)
static

Definition at line 815 of file varlena.c.

References cstring_to_text(), DatumGetPointer, DatumGetTextPSlice, elog, ereport, errcode(), errmsg(), ERROR, i, length(), Max, Min, palloc(), pfree(), pg_database_encoding_max_length(), pg_mblen(), pg_mbstrlen_with_len(), S, SET_VARSIZE, VARATT_IS_COMPRESSED, VARATT_IS_EXTERNAL, VARDATA, VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

Referenced by split_text(), text_overlay(), text_substr(), and text_substr_no_len().

816 {
818  int32 S = start; /* start position */
819  int32 S1; /* adjusted start position */
820  int32 L1; /* adjusted substring length */
821 
822  /* life is easy if the encoding max length is 1 */
823  if (eml == 1)
824  {
825  S1 = Max(S, 1);
826 
827  if (length_not_specified) /* special case - get length to end of
828  * string */
829  L1 = -1;
830  else
831  {
832  /* end position */
833  int E = S + length;
834 
835  /*
836  * A negative value for L is the only way for the end position to
837  * be before the start. SQL99 says to throw an error.
838  */
839  if (E < S)
840  ereport(ERROR,
841  (errcode(ERRCODE_SUBSTRING_ERROR),
842  errmsg("negative substring length not allowed")));
843 
844  /*
845  * A zero or negative value for the end position can happen if the
846  * start was negative or one. SQL99 says to return a zero-length
847  * string.
848  */
849  if (E < 1)
850  return cstring_to_text("");
851 
852  L1 = E - S1;
853  }
854 
855  /*
856  * If the start position is past the end of the string, SQL99 says to
857  * return a zero-length string -- PG_GETARG_TEXT_P_SLICE() will do
858  * that for us. Convert to zero-based starting position
859  */
860  return DatumGetTextPSlice(str, S1 - 1, L1);
861  }
862  else if (eml > 1)
863  {
864  /*
865  * When encoding max length is > 1, we can't get LC without
866  * detoasting, so we'll grab a conservatively large slice now and go
867  * back later to do the right thing
868  */
869  int32 slice_start;
870  int32 slice_size;
871  int32 slice_strlen;
872  text *slice;
873  int32 E1;
874  int32 i;
875  char *p;
876  char *s;
877  text *ret;
878 
879  /*
880  * if S is past the end of the string, the tuple toaster will return a
881  * zero-length string to us
882  */
883  S1 = Max(S, 1);
884 
885  /*
886  * We need to start at position zero because there is no way to know
887  * in advance which byte offset corresponds to the supplied start
888  * position.
889  */
890  slice_start = 0;
891 
892  if (length_not_specified) /* special case - get length to end of
893  * string */
894  slice_size = L1 = -1;
895  else
896  {
897  int E = S + length;
898 
899  /*
900  * A negative value for L is the only way for the end position to
901  * be before the start. SQL99 says to throw an error.
902  */
903  if (E < S)
904  ereport(ERROR,
905  (errcode(ERRCODE_SUBSTRING_ERROR),
906  errmsg("negative substring length not allowed")));
907 
908  /*
909  * A zero or negative value for the end position can happen if the
910  * start was negative or one. SQL99 says to return a zero-length
911  * string.
912  */
913  if (E < 1)
914  return cstring_to_text("");
915 
916  /*
917  * if E is past the end of the string, the tuple toaster will
918  * truncate the length for us
919  */
920  L1 = E - S1;
921 
922  /*
923  * Total slice size in bytes can't be any longer than the start
924  * position plus substring length times the encoding max length.
925  */
926  slice_size = (S1 + L1) * eml;
927  }
928 
929  /*
930  * If we're working with an untoasted source, no need to do an extra
931  * copying step.
932  */
935  slice = DatumGetTextPSlice(str, slice_start, slice_size);
936  else
937  slice = (text *) DatumGetPointer(str);
938 
939  /* see if we got back an empty string */
940  if (VARSIZE_ANY_EXHDR(slice) == 0)
941  {
942  if (slice != (text *) DatumGetPointer(str))
943  pfree(slice);
944  return cstring_to_text("");
945  }
946 
947  /* Now we can get the actual length of the slice in MB characters */
948  slice_strlen = pg_mbstrlen_with_len(VARDATA_ANY(slice),
949  VARSIZE_ANY_EXHDR(slice));
950 
951  /*
952  * Check that the start position wasn't > slice_strlen. If so, SQL99
953  * says to return a zero-length string.
954  */
955  if (S1 > slice_strlen)
956  {
957  if (slice != (text *) DatumGetPointer(str))
958  pfree(slice);
959  return cstring_to_text("");
960  }
961 
962  /*
963  * Adjust L1 and E1 now that we know the slice string length. Again
964  * remember that S1 is one based, and slice_start is zero based.
965  */
966  if (L1 > -1)
967  E1 = Min(S1 + L1, slice_start + 1 + slice_strlen);
968  else
969  E1 = slice_start + 1 + slice_strlen;
970 
971  /*
972  * Find the start position in the slice; remember S1 is not zero based
973  */
974  p = VARDATA_ANY(slice);
975  for (i = 0; i < S1 - 1; i++)
976  p += pg_mblen(p);
977 
978  /* hang onto a pointer to our start position */
979  s = p;
980 
981  /*
982  * Count the actual bytes used by the substring of the requested
983  * length.
984  */
985  for (i = S1; i < E1; i++)
986  p += pg_mblen(p);
987 
988  ret = (text *) palloc(VARHDRSZ + (p - s));
989  SET_VARSIZE(ret, VARHDRSZ + (p - s));