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

Go to the source code of this file.

Data Structures

struct  TextPositionState
 
struct  VarStringSortSupport
 
struct  SplitTextOutputData
 

Macros

#define TEXTBUFLEN   1024
 
#define DatumGetUnknownP(X)   ((unknown *) PG_DETOAST_DATUM(X))
 
#define DatumGetUnknownPCopy(X)   ((unknown *) PG_DETOAST_DATUM_COPY(X))
 
#define PG_GETARG_UNKNOWN_P(n)   DatumGetUnknownP(PG_GETARG_DATUM(n))
 
#define PG_GETARG_UNKNOWN_P_COPY(n)   DatumGetUnknownPCopy(PG_GETARG_DATUM(n))
 
#define PG_RETURN_UNKNOWN_P(x)   PG_RETURN_POINTER(x)
 
#define DatumGetVarStringP(X)   ((VarString *) PG_DETOAST_DATUM(X))
 
#define DatumGetVarStringPP(X)   ((VarString *) PG_DETOAST_DATUM_PACKED(X))
 
#define VAL(CH)   ((CH) - '0')
 
#define DIG(VAL)   ((VAL) + '0')
 
#define CmpCall(cmpfunc)
 
#define PG_STR_GET_BYTEA(str_)   DatumGetByteaPP(DirectFunctionCall1(byteain, CStringGetDatum(str_)))
 
#define REGEXP_REPLACE_BACKREF_CNT   10
 
#define HEXBASE   16
 
#define TEXT_FORMAT_FLAG_MINUS   0x0001 /* is minus flag present? */
 
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
 
#define LEVENSHTEIN_LESS_EQUAL
 

Typedefs

typedef struct varlena unknown
 
typedef struct varlena VarString
 

Functions

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

Variables

int bytea_output = BYTEA_OUTPUT_HEX
 

Macro Definition Documentation

◆ ADVANCE_PARSE_POINTER

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

Definition at line 5692 of file varlena.c.

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

◆ CmpCall

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

Definition at line 3027 of file varlena.c.

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

◆ DatumGetUnknownP

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

Definition at line 115 of file varlena.c.

◆ DatumGetUnknownPCopy

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

Definition at line 116 of file varlena.c.

◆ DatumGetVarStringP

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

Definition at line 121 of file varlena.c.

◆ DatumGetVarStringPP

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

Definition at line 122 of file varlena.c.

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

◆ DIG

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

Definition at line 282 of file varlena.c.

Referenced by byteaout().

◆ HEXBASE

#define HEXBASE   16

Definition at line 5217 of file varlena.c.

Referenced by to_hex32(), and to_hex64().

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

Definition at line 6232 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P

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

Definition at line 117 of file varlena.c.

◆ PG_GETARG_UNKNOWN_P_COPY

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

Definition at line 118 of file varlena.c.

◆ PG_RETURN_UNKNOWN_P

#define PG_RETURN_UNKNOWN_P (   x)    PG_RETURN_POINTER(x)

Definition at line 119 of file varlena.c.

◆ PG_STR_GET_BYTEA

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

Definition at line 3282 of file varlena.c.

Referenced by bytea_substring().

◆ REGEXP_REPLACE_BACKREF_CNT

#define REGEXP_REPLACE_BACKREF_CNT   10

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

Referenced by text_format_append_string(), and text_format_parse_format().

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 113 of file varlena.c.

Referenced by varstr_cmp(), and varstr_sortsupport().

◆ VAL

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

Definition at line 281 of file varlena.c.

Referenced by byteain().

Typedef Documentation

◆ unknown

typedef struct varlena unknown

Definition at line 47 of file varlena.c.

◆ VarString

typedef struct varlena VarString

Definition at line 48 of file varlena.c.

Function Documentation

◆ appendStringInfoRegexpSubstr()

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

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

4403 {
4404  const char *p = VARDATA_ANY(replace_text);
4405  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4406  int eml = pg_database_encoding_max_length();
4407 
4408  for (;;)
4409  {
4410  const char *chunk_start = p;
4411  int so;
4412  int eo;
4413 
4414  /* Find next escape char. */
4415  if (eml == 1)
4416  {
4417  for (; p < p_end && *p != '\\'; p++)
4418  /* nothing */ ;
4419  }
4420  else
4421  {
4422  for (; p < p_end && *p != '\\'; p += pg_mblen(p))
4423  /* nothing */ ;
4424  }
4425 
4426  /* Copy the text we just scanned over, if any. */
4427  if (p > chunk_start)
4428  appendBinaryStringInfo(str, chunk_start, p - chunk_start);
4429 
4430  /* Done if at end of string, else advance over escape char. */
4431  if (p >= p_end)
4432  break;
4433  p++;
4434 
4435  if (p >= p_end)
4436  {
4437  /* Escape at very end of input. Treat same as unexpected char */
4438  appendStringInfoChar(str, '\\');
4439  break;
4440  }
4441 
4442  if (*p >= '1' && *p <= '9')
4443  {
4444  /* Use the back reference of regexp. */
4445  int idx = *p - '0';
4446 
4447  so = pmatch[idx].rm_so;
4448  eo = pmatch[idx].rm_eo;
4449  p++;
4450  }
4451  else if (*p == '&')
4452  {
4453  /* Use the entire matched string. */
4454  so = pmatch[0].rm_so;
4455  eo = pmatch[0].rm_eo;
4456  p++;
4457  }
4458  else if (*p == '\\')
4459  {
4460  /* \\ means transfer one \ to output. */
4461  appendStringInfoChar(str, '\\');
4462  p++;
4463  continue;
4464  }
4465  else
4466  {
4467  /*
4468  * If escape char is not followed by any expected char, just treat
4469  * it as ordinary data to copy. (XXX would it be better to throw
4470  * an error?)
4471  */
4472  appendStringInfoChar(str, '\\');
4473  continue;
4474  }
4475 
4476  if (so != -1 && eo != -1)
4477  {
4478  /*
4479  * Copy the text that is back reference of regexp. Note so and eo
4480  * are counted in characters not bytes.
4481  */
4482  char *chunk_start;
4483  int chunk_len;
4484 
4485  Assert(so >= data_pos);
4486  chunk_start = start_ptr;
4487  chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
4488  chunk_len = charlen_to_bytelen(chunk_start, eo - so);
4489  appendBinaryStringInfo(str, chunk_start, chunk_len);
4490  }
4491  }
4492 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
regoff_t rm_so
Definition: regex.h:87
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
regoff_t rm_eo
Definition: regex.h:88
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:793
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
#define Assert(condition)
Definition: c.h:804
int pg_mblen(const char *mbstr)
Definition: mbutils.c:966
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ appendStringInfoText()

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

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

4279 {
4281 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

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

5059 {
5061  char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
5062 
5063  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
5064 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:5100
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
char * text_to_cstring(const text *t)
Definition: varlena.c:223

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

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

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

5102 {
5103  text *result;
5104  int nitems,
5105  *dims,
5106  ndims;
5107  Oid element_type;
5108  int typlen;
5109  bool typbyval;
5110  char typalign;
5112  bool printed = false;
5113  char *p;
5114  bits8 *bitmap;
5115  int bitmask;
5116  int i;
5117  ArrayMetaState *my_extra;
5118 
5119  ndims = ARR_NDIM(v);
5120  dims = ARR_DIMS(v);
5121  nitems = ArrayGetNItems(ndims, dims);
5122 
5123  /* if there are no elements, return an empty string */
5124  if (nitems == 0)
5125  return cstring_to_text_with_len("", 0);
5126 
5127  element_type = ARR_ELEMTYPE(v);
5128  initStringInfo(&buf);
5129 
5130  /*
5131  * We arrange to look up info about element type, including its output
5132  * conversion proc, only once per series of calls, assuming the element
5133  * type doesn't change underneath us.
5134  */
5135  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
5136  if (my_extra == NULL)
5137  {
5138  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5139  sizeof(ArrayMetaState));
5140  my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
5141  my_extra->element_type = ~element_type;
5142  }
5143 
5144  if (my_extra->element_type != element_type)
5145  {
5146  /*
5147  * Get info about element type, including its output conversion proc
5148  */
5149  get_type_io_data(element_type, IOFunc_output,
5150  &my_extra->typlen, &my_extra->typbyval,
5151  &my_extra->typalign, &my_extra->typdelim,
5152  &my_extra->typioparam, &my_extra->typiofunc);
5153  fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
5154  fcinfo->flinfo->fn_mcxt);
5155  my_extra->element_type = element_type;
5156  }
5157  typlen = my_extra->typlen;
5158  typbyval = my_extra->typbyval;
5159  typalign = my_extra->typalign;
5160 
5161  p = ARR_DATA_PTR(v);
5162  bitmap = ARR_NULLBITMAP(v);
5163  bitmask = 1;
5164 
5165  for (i = 0; i < nitems; i++)
5166  {
5167  Datum itemvalue;
5168  char *value;
5169 
5170  /* Get source element, checking for NULL */
5171  if (bitmap && (*bitmap & bitmask) == 0)
5172  {
5173  /* if null_string is NULL, we just ignore null elements */
5174  if (null_string != NULL)
5175  {
5176  if (printed)
5177  appendStringInfo(&buf, "%s%s", fldsep, null_string);
5178  else
5179  appendStringInfoString(&buf, null_string);
5180  printed = true;
5181  }
5182  }
5183  else
5184  {
5185  itemvalue = fetch_att(p, typbyval, typlen);
5186 
5187  value = OutputFunctionCall(&my_extra->proc, itemvalue);
5188 
5189  if (printed)
5190  appendStringInfo(&buf, "%s%s", fldsep, value);
5191  else
5192  appendStringInfoString(&buf, value);
5193  printed = true;
5194 
5195  p = att_addlength_pointer(p, typlen, p);
5196  p = (char *) att_align_nominal(p, typalign);
5197  }
5198 
5199  /* advance bitmap pointer if any */
5200  if (bitmap)
5201  {
5202  bitmask <<= 1;
5203  if (bitmask == 0x100)
5204  {
5205  bitmap++;
5206  bitmask = 1;
5207  }
5208  }
5209  }
5210 
5211  result = cstring_to_text_with_len(buf.data, buf.len);
5212  pfree(buf.data);
5213 
5214  return result;
5215 }
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:76
unsigned int Oid
Definition: postgres_ext.h:31
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1573
bool typbyval
Definition: array.h:233
void pfree(void *pointer)
Definition: mcxt.c:1169
char typalign
Definition: pg_type.h:176
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ARR_DIMS(a)
Definition: array.h:287
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
#define ARR_DATA_PTR(a)
Definition: array.h:315
int16 typlen
Definition: array.h:232
static char * buf
Definition: pg_test_fsync.c:68
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
char typdelim
Definition: array.h:235
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uint8 bits8
Definition: c.h:448
uintptr_t Datum
Definition: postgres.h:411
FmgrInfo * flinfo
Definition: fmgr.h:87
static struct @143 value
Oid typioparam
Definition: array.h:236
void * fn_extra
Definition: fmgr.h:64
#define ARR_NDIM(a)
Definition: array.h:283
Oid typiofunc
Definition: array.h:237
char typalign
Definition: array.h:234
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:75
FmgrInfo proc
Definition: array.h:238
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
int i
Oid element_type
Definition: array.h:231
Definition: c.h:621
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define ARR_NULLBITMAP(a)
Definition: array.h:293
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:2272

◆ array_to_text_null()

Datum array_to_text_null ( PG_FUNCTION_ARGS  )

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

5075 {
5076  ArrayType *v;
5077  char *fldsep;
5078  char *null_string;
5079 
5080  /* returns NULL when first or second parameter is NULL */
5081  if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
5082  PG_RETURN_NULL();
5083 
5084  v = PG_GETARG_ARRAYTYPE_P(0);
5085  fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
5086 
5087  /* NULL null string is passed through as a null pointer */
5088  if (!PG_ARGISNULL(2))
5089  null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
5090  else
5091  null_string = NULL;
5092 
5093  PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
5094 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:5100
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
char * text_to_cstring(const text *t)
Definition: varlena.c:223
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ bpcharfastcmp_c()

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

Definition at line 2226 of file varlena.c.

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

Referenced by varstr_sortsupport().

2227 {
2228  BpChar *arg1 = DatumGetBpCharPP(x);
2229  BpChar *arg2 = DatumGetBpCharPP(y);
2230  char *a1p,
2231  *a2p;
2232  int len1,
2233  len2,
2234  result;
2235 
2236  a1p = VARDATA_ANY(arg1);
2237  a2p = VARDATA_ANY(arg2);
2238 
2239  len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2240  len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2241 
2242  result = memcmp(a1p, a2p, Min(len1, len2));
2243  if ((result == 0) && (len1 != len2))
2244  result = (len1 < len2) ? -1 : 1;
2245 
2246  /* We can't afford to leak memory here. */
2247  if (PointerGetDatum(arg1) != x)
2248  pfree(arg1);
2249  if (PointerGetDatum(arg2) != y)
2250  pfree(arg2);
2251 
2252  return result;
2253 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PointerGetDatum(X)
Definition: postgres.h:600
#define Min(x, y)
Definition: c.h:986
void pfree(void *pointer)
Definition: mcxt.c:1169
int bpchartruelen(char *s, int len)
Definition: varchar.c:671
#define DatumGetBpCharPP(X)
Definition: fmgr.h:293
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621

◆ btnametextcmp()

Datum btnametextcmp ( PG_FUNCTION_ARGS  )

Definition at line 2996 of file varlena.c.

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

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

2997 {
2998  Name arg1 = PG_GETARG_NAME(0);
2999  text *arg2 = PG_GETARG_TEXT_PP(1);
3000  int32 result;
3001 
3002  result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
3003  VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
3004  PG_GET_COLLATION());
3005 
3006  PG_FREE_IF_COPY(arg2, 1);
3007 
3008  PG_RETURN_INT32(result);
3009 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:429
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1542
Definition: c.h:675
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
#define NameStr(name)
Definition: c.h:681
Definition: c.h:621
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 3179 of file varlena.c.

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

3180 {
3181  text *arg1 = PG_GETARG_TEXT_PP(0);
3182  text *arg2 = PG_GETARG_TEXT_PP(1);
3183  int result;
3184 
3185  result = internal_text_pattern_compare(arg1, arg2);
3186 
3187  PG_FREE_IF_COPY(arg1, 0);
3188  PG_FREE_IF_COPY(arg2, 1);
3189 
3190  PG_RETURN_INT32(result);
3191 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:3093
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 3195 of file varlena.c.

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

3196 {
3198  MemoryContext oldcontext;
3199 
3200  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
3201 
3202  /* Use generic string SortSupport, forcing "C" collation */
3203  varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID);
3204 
3205  MemoryContextSwitchTo(oldcontext);
3206 
3207  PG_RETURN_VOID();
3208 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:2027
#define PG_RETURN_VOID()
Definition: fmgr.h:349

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

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

1986 {
1987  text *arg1 = PG_GETARG_TEXT_PP(0);
1988  text *arg2 = PG_GETARG_TEXT_PP(1);
1989  int32 result;
1990 
1991  result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1992 
1993  PG_FREE_IF_COPY(arg1, 0);
1994  PG_FREE_IF_COPY(arg2, 1);
1995 
1996  PG_RETURN_INT32(result);
1997 }
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:429
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1758
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ bttextnamecmp()

Datum bttextnamecmp ( PG_FUNCTION_ARGS  )

Definition at line 3012 of file varlena.c.

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

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

3013 {
3014  text *arg1 = PG_GETARG_TEXT_PP(0);
3015  Name arg2 = PG_GETARG_NAME(1);
3016  int32 result;
3017 
3018  result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
3019  NameStr(*arg2), strlen(NameStr(*arg2)),
3020  PG_GET_COLLATION());
3021 
3022  PG_FREE_IF_COPY(arg1, 0);
3023 
3024  PG_RETURN_INT32(result);
3025 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GET_COLLATION()
Definition: fmgr.h:198
signed int int32
Definition: c.h:429
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1542
Definition: c.h:675
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
#define NameStr(name)
Definition: c.h:681
Definition: c.h:621
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2000 of file varlena.c.

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

2001 {
2003  Oid collid = ssup->ssup_collation;
2004  MemoryContext oldcontext;
2005 
2006  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2007 
2008  /* Use generic string SortSupport */
2009  varstr_sortsupport(ssup, TEXTOID, collid);
2010 
2011  MemoryContextSwitchTo(oldcontext);
2012 
2013  PG_RETURN_VOID();
2014 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
unsigned int Oid
Definition: postgres_ext.h:31
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:2027
#define PG_RETURN_VOID()
Definition: fmgr.h:349

◆ btvarstrequalimage()

Datum btvarstrequalimage ( PG_FUNCTION_ARGS  )

Definition at line 2851 of file varlena.c.

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

2852 {
2853  /* Oid opcintype = PG_GETARG_OID(0); */
2854  Oid collid = PG_GET_COLLATION();
2855 
2856  check_collation_set(collid);
2857 
2858  if (lc_collate_is_c(collid) ||
2859  collid == DEFAULT_COLLATION_OID ||
2861  PG_RETURN_BOOL(true);
2862  else
2863  PG_RETURN_BOOL(false);
2864 }
bool get_collation_isdeterministic(Oid colloid)
Definition: lsyscache.c:1079
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
bool lc_collate_is_c(Oid collation)
Definition: pg_locale.c:1321
static void check_collation_set(Oid collid)
Definition: varlena.c:1513
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

◆ build_concat_foutcache()

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

Definition at line 5451 of file varlena.c.

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

Referenced by concat_internal().

5452 {
5453  FmgrInfo *foutcache;
5454  int i;
5455 
5456  /* We keep the info in fn_mcxt so it survives across calls */
5457  foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5458  PG_NARGS() * sizeof(FmgrInfo));
5459 
5460  for (i = argidx; i < PG_NARGS(); i++)
5461  {
5462  Oid valtype;
5463  Oid typOutput;
5464  bool typIsVarlena;
5465 
5466  valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5467  if (!OidIsValid(valtype))
5468  elog(ERROR, "could not determine data type of concat() input");
5469 
5470  getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5471  fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5472  }
5473 
5474  fcinfo->flinfo->fn_extra = foutcache;
5475 
5476  return foutcache;
5477 }
Definition: fmgr.h:56
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854
MemoryContext fn_mcxt
Definition: fmgr.h:65
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
FmgrInfo * flinfo
Definition: fmgr.h:87
struct FmgrInfo FmgrInfo
#define PG_NARGS()
Definition: fmgr.h:203
void * fn_extra
Definition: fmgr.h:64
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define elog(elevel,...)
Definition: elog.h:232
int i

◆ bytea_bit_count()

Datum bytea_bit_count ( PG_FUNCTION_ARGS  )

Definition at line 3447 of file varlena.c.

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

3448 {
3449  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3450 
3452 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.c:282
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621

◆ bytea_catenate()

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

Definition at line 3249 of file varlena.c.

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

Referenced by bytea_overlay(), and byteacat().

3250 {
3251  bytea *result;
3252  int len1,
3253  len2,
3254  len;
3255  char *ptr;
3256 
3257  len1 = VARSIZE_ANY_EXHDR(t1);
3258  len2 = VARSIZE_ANY_EXHDR(t2);
3259 
3260  /* paranoia ... probably should throw error instead? */
3261  if (len1 < 0)
3262  len1 = 0;
3263  if (len2 < 0)
3264  len2 = 0;
3265 
3266  len = len1 + len2 + VARHDRSZ;
3267  result = (bytea *) palloc(len);
3268 
3269  /* Set size of result string... */
3270  SET_VARSIZE(result, len);
3271 
3272  /* Fill data field of result string... */
3273  ptr = VARDATA(result);
3274  if (len1 > 0)
3275  memcpy(ptr, VARDATA_ANY(t1), len1);
3276  if (len2 > 0)
3277  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
3278 
3279  return result;
3280 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARHDRSZ
Definition: c.h:627
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: c.h:621
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ bytea_overlay()

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

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

3415 {
3416  bytea *result;
3417  bytea *s1;
3418  bytea *s2;
3419  int sp_pl_sl;
3420 
3421  /*
3422  * Check for possible integer-overflow cases. For negative sp, throw a
3423  * "substring length" error because that's what should be expected
3424  * according to the spec's definition of OVERLAY().
3425  */
3426  if (sp <= 0)
3427  ereport(ERROR,
3428  (errcode(ERRCODE_SUBSTRING_ERROR),
3429  errmsg("negative substring length not allowed")));
3430  if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
3431  ereport(ERROR,
3432  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3433  errmsg("integer out of range")));
3434 
3435  s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
3436  s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
3437  result = bytea_catenate(s1, t2);
3438  result = bytea_catenate(result, s2);
3439 
3440  return result;
3441 }
#define PointerGetDatum(X)
Definition: postgres.h:600
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3249
int errcode(int sqlerrcode)
Definition: elog.c:698
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3324
#define ERROR
Definition: elog.h:46
char * s1
char * s2
#define ereport(elevel,...)
Definition: elog.h:157
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 4256 of file varlena.c.

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

4257 {
4259  MemoryContext oldcontext;
4260 
4261  oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
4262 
4263  /* Use generic string SortSupport, forcing "C" collation */
4264  varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
4265 
4266  MemoryContextSwitchTo(oldcontext);
4267 
4268  PG_RETURN_VOID();
4269 }
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:2027
#define PG_RETURN_VOID()
Definition: fmgr.h:349

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

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

541 {
543 
544  /* cannot be called directly because of internal-type argument */
545  Assert(AggCheckCallContext(fcinfo, NULL));
546 
547  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
548 
549  if (state != NULL)
550  {
551  bytea *result;
552 
553  result = (bytea *) palloc(state->len + VARHDRSZ);
554  SET_VARSIZE(result, state->len + VARHDRSZ);
555  memcpy(VARDATA(result), state->data, state->len);
556  PG_RETURN_BYTEA_P(result);
557  }
558  else
559  PG_RETURN_NULL();
560 }
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARHDRSZ
Definition: c.h:627
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
ts_parserstate state
Definition: tsquery.c:80
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:804
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4580
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: c.h:621
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

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

509 {
511 
512  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
513 
514  /* Append the value unless null. */
515  if (!PG_ARGISNULL(1))
516  {
518 
519  /* On the first time through, we ignore the delimiter. */
520  if (state == NULL)
521  state = makeStringAggState(fcinfo);
522  else if (!PG_ARGISNULL(2))
523  {
524  bytea *delim = PG_GETARG_BYTEA_PP(2);
525 
527  }
528 
530  }
531 
532  /*
533  * The transition type for string_agg() is declared to be "internal",
534  * which is a pass-by-value type the same size as a pointer.
535  */
536  PG_RETURN_POINTER(state);
537 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
ts_parserstate state
Definition: tsquery.c:80
static struct @143 value
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5379
Definition: c.h:621
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 3301 of file varlena.c.

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

3302 {
3304  PG_GETARG_INT32(1),
3305  PG_GETARG_INT32(2),
3306  false));
3307 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3324

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3315 of file varlena.c.

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

3316 {
3318  PG_GETARG_INT32(1),
3319  -1,
3320  true));
3321 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3324

◆ bytea_substring()

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

Definition at line 3324 of file varlena.c.

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

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

3328 {
3329  int32 S1; /* adjusted start position */
3330  int32 L1; /* adjusted substring length */
3331  int32 E; /* end position */
3332 
3333  /*
3334  * The logic here should generally match text_substring().
3335  */
3336  S1 = Max(S, 1);
3337 
3338  if (length_not_specified)
3339  {
3340  /*
3341  * Not passed a length - DatumGetByteaPSlice() grabs everything to the
3342  * end of the string if we pass it a negative value for length.
3343  */
3344  L1 = -1;
3345  }
3346  else if (L < 0)
3347  {
3348  /* SQL99 says to throw an error for E < S, i.e., negative length */
3349  ereport(ERROR,
3350  (errcode(ERRCODE_SUBSTRING_ERROR),
3351  errmsg("negative substring length not allowed")));
3352  L1 = -1; /* silence stupider compilers */
3353  }
3354  else if (pg_add_s32_overflow(S, L, &E))
3355  {
3356  /*
3357  * L could be large enough for S + L to overflow, in which case the
3358  * substring must run to end of string.
3359  */
3360  L1 = -1;
3361  }
3362  else
3363  {
3364  /*
3365  * A zero or negative value for the end position can happen if the
3366  * start was negative or one. SQL99 says to return a zero-length
3367  * string.
3368  */
3369  if (E < 1)
3370  return PG_STR_GET_BYTEA("");
3371 
3372  L1 = E - S1;
3373  }
3374 
3375  /*
3376  * If the start position is past the end of the string, SQL99 says to
3377  * return a zero-length string -- DatumGetByteaPSlice() will do that for
3378  * us. We need only convert S1 to zero-based starting position.
3379  */
3380  return DatumGetByteaPSlice(str, S1 - 1, L1);
3381 }
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:303
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:3282
#define ERROR
Definition: elog.h:46
#define S(n, x)
Definition: sha1.c:73
#define ereport(elevel,...)
Definition: elog.h:157
#define Max(x, y)
Definition: c.h:980
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 3234 of file varlena.c.

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

3235 {
3236  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3237  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3238 
3240 }
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3249
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
Definition: c.h:621

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

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

4235 {
4236  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4237  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4238  int len1,
4239  len2;
4240  int cmp;
4241 
4242  len1 = VARSIZE_ANY_EXHDR(arg1);
4243  len2 = VARSIZE_ANY_EXHDR(arg2);
4244 
4245  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4246  if ((cmp == 0) && (len1 != len2))
4247  cmp = (len1 < len2) ? -1 : 1;
4248 
4249  PG_FREE_IF_COPY(arg1, 0);
4250  PG_FREE_IF_COPY(arg2, 1);
4251 
4252  PG_RETURN_INT32(cmp);
4253 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define Min(x, y)
Definition: c.h:986
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ byteaeq()

Datum byteaeq ( PG_FUNCTION_ARGS  )

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

4091 {
4092  Datum arg1 = PG_GETARG_DATUM(0);
4093  Datum arg2 = PG_GETARG_DATUM(1);
4094  bool result;
4095  Size len1,
4096  len2;
4097 
4098  /*
4099  * We can use a fast path for unequal lengths, which might save us from
4100  * having to detoast one or both values.
4101  */
4102  len1 = toast_raw_datum_size(arg1);
4103  len2 = toast_raw_datum_size(arg2);
4104  if (len1 != len2)
4105  result = false;
4106  else
4107  {
4108  bytea *barg1 = DatumGetByteaPP(arg1);
4109  bytea *barg2 = DatumGetByteaPP(arg2);
4110 
4111  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4112  len1 - VARHDRSZ) == 0);
4113 
4114  PG_FREE_IF_COPY(barg1, 0);
4115  PG_FREE_IF_COPY(barg2, 1);
4116  }
4117 
4118  PG_RETURN_BOOL(result);
4119 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define VARHDRSZ
Definition: c.h:627
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
size_t Size
Definition: c.h:540
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

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

4215 {
4216  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4217  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4218  int len1,
4219  len2;
4220  int cmp;
4221 
4222  len1 = VARSIZE_ANY_EXHDR(arg1);
4223  len2 = VARSIZE_ANY_EXHDR(arg2);
4224 
4225  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4226 
4227  PG_FREE_IF_COPY(arg1, 0);
4228  PG_FREE_IF_COPY(arg2, 1);
4229 
4230  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
4231 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define Min(x, y)
Definition: c.h:986
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ byteaGetBit()

Datum byteaGetBit ( PG_FUNCTION_ARGS  )

Definition at line 3534 of file varlena.c.

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

3535 {
3536  bytea *v = PG_GETARG_BYTEA_PP(0);
3537  int64 n = PG_GETARG_INT64(1);
3538  int byteNo,
3539  bitNo;
3540  int len;
3541  int byte;
3542 
3543  len = VARSIZE_ANY_EXHDR(v);
3544 
3545  if (n < 0 || n >= (int64) len * 8)
3546  ereport(ERROR,
3547  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3548  errmsg("index %lld out of valid range, 0..%lld",
3549  (long long) n, (long long) len * 8 - 1)));
3550 
3551  /* n/8 is now known < len, so safe to cast to int */
3552  byteNo = (int) (n / 8);
3553  bitNo = (int) (n % 8);
3554 
3555  byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3556 
3557  if (byte & (1 << bitNo))
3558  PG_RETURN_INT32(1);
3559  else
3560  PG_RETURN_INT32(0);
3561 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define byte(x, n)
Definition: rijndael.c:68
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

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

3506 {
3507  bytea *v = PG_GETARG_BYTEA_PP(0);
3508  int32 n = PG_GETARG_INT32(1);
3509  int len;
3510  int byte;
3511 
3512  len = VARSIZE_ANY_EXHDR(v);
3513 
3514  if (n < 0 || n >= len)
3515  ereport(ERROR,
3516  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3517  errmsg("index %d out of valid range, 0..%d",
3518  n, len - 1)));
3519 
3520  byte = ((unsigned char *) VARDATA_ANY(v))[n];
3521 
3522  PG_RETURN_INT32(byte);
3523 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
int errcode(int sqlerrcode)
Definition: elog.c:698
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define byte(x, n)
Definition: rijndael.c:68
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

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

4195 {
4196  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4197  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4198  int len1,
4199  len2;
4200  int cmp;
4201 
4202  len1 = VARSIZE_ANY_EXHDR(arg1);
4203  len2 = VARSIZE_ANY_EXHDR(arg2);
4204 
4205  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4206 
4207  PG_FREE_IF_COPY(arg1, 0);
4208  PG_FREE_IF_COPY(arg2, 1);
4209 
4210  PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
4211 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define Min(x, y)
Definition: c.h:986
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ byteain()

Datum byteain ( PG_FUNCTION_ARGS  )

Definition at line 296 of file varlena.c.

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

Referenced by CreateTriggerFiringOn(), and string_to_datum().

297 {
298  char *inputText = PG_GETARG_CSTRING(0);
299  char *tp;
300  char *rp;
301  int bc;
302  bytea *result;
303 
304  /* Recognize hex input */
305  if (inputText[0] == '\\' && inputText[1] == 'x')
306  {
307  size_t len = strlen(inputText);
308  uint64 dstlen = pg_hex_dec_len(len - 2);
309 
310  bc = dstlen + VARHDRSZ; /* maximum possible length */
311  result = palloc(bc);
312 
313  bc = pg_hex_decode(inputText + 2, len - 2, VARDATA(result), dstlen);
314  SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */
315 
316  PG_RETURN_BYTEA_P(result);
317  }
318 
319  /* Else, it's the traditional escaped style */
320  for (bc = 0, tp = inputText; *tp != '\0'; bc++)
321  {
322  if (tp[0] != '\\')
323  tp++;
324  else if ((tp[0] == '\\') &&
325  (tp[1] >= '0' && tp[1] <= '3') &&
326  (tp[2] >= '0' && tp[2] <= '7') &&
327  (tp[3] >= '0' && tp[3] <= '7'))
328  tp += 4;
329  else if ((tp[0] == '\\') &&
330  (tp[1] == '\\'))
331  tp += 2;
332  else
333  {
334  /*
335  * one backslash, not followed by another or ### valid octal
336  */
337  ereport(ERROR,
338  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
339  errmsg("invalid input syntax for type %s", "bytea")));
340  }
341  }
342 
343  bc += VARHDRSZ;
344 
345  result = (bytea *) palloc(bc);
346  SET_VARSIZE(result, bc);
347 
348  tp = inputText;
349  rp = VARDATA(result);
350  while (*tp != '\0')
351  {
352  if (tp[0] != '\\')
353  *rp++ = *tp++;
354  else if ((tp[0] == '\\') &&
355  (tp[1] >= '0' && tp[1] <= '3') &&
356  (tp[2] >= '0' && tp[2] <= '7') &&
357  (tp[3] >= '0' && tp[3] <= '7'))
358  {
359  bc = VAL(tp[1]);
360  bc <<= 3;
361  bc += VAL(tp[2]);
362  bc <<= 3;
363  *rp++ = bc + VAL(tp[3]);
364 
365  tp += 4;
366  }
367  else if ((tp[0] == '\\') &&
368  (tp[1] == '\\'))
369  {
370  *rp++ = '\\';
371  tp += 2;
372  }
373  else
374  {
375  /*
376  * We should never get here. The first pass should not allow it.
377  */
378  ereport(ERROR,
379  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
380  errmsg("invalid input syntax for type %s", "bytea")));
381  }
382  }
383 
384  PG_RETURN_BYTEA_P(result);
385 }
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARHDRSZ
Definition: c.h:627
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
uint64 pg_hex_dec_len(size_t srclen)
Definition: hex.c:189
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
uint64 pg_hex_decode(const char *src, size_t srclen, char *dst, size_t dstlen)
Definition: hex.c:112
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define VAL(CH)
Definition: varlena.c:281
Definition: c.h:621
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

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

4175 {
4176  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4177  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4178  int len1,
4179  len2;
4180  int cmp;
4181 
4182  len1 = VARSIZE_ANY_EXHDR(arg1);
4183  len2 = VARSIZE_ANY_EXHDR(arg2);
4184 
4185  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4186 
4187  PG_FREE_IF_COPY(arg1, 0);
4188  PG_FREE_IF_COPY(arg2, 1);
4189 
4190  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
4191 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define Min(x, y)
Definition: c.h:986
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ bytealt()

Datum bytealt ( PG_FUNCTION_ARGS  )

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

4155 {
4156  bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4157  bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4158  int len1,
4159  len2;
4160  int cmp;
4161 
4162  len1 = VARSIZE_ANY_EXHDR(arg1);
4163  len2 = VARSIZE_ANY_EXHDR(arg2);
4164 
4165  cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4166 
4167  PG_FREE_IF_COPY(arg1, 0);
4168  PG_FREE_IF_COPY(arg2, 1);
4169 
4170  PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
4171 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define Min(x, y)
Definition: c.h:986
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ byteane()

Datum byteane ( PG_FUNCTION_ARGS  )

Definition at line 4122 of file varlena.c.

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

4123 {
4124  Datum arg1 = PG_GETARG_DATUM(0);
4125  Datum arg2 = PG_GETARG_DATUM(1);
4126  bool result;
4127  Size len1,
4128  len2;
4129 
4130  /*
4131  * We can use a fast path for unequal lengths, which might save us from
4132  * having to detoast one or both values.
4133  */
4134  len1 = toast_raw_datum_size(arg1);
4135  len2 = toast_raw_datum_size(arg2);
4136  if (len1 != len2)
4137  result = true;
4138  else
4139  {
4140  bytea *barg1 = DatumGetByteaPP(arg1);
4141  bytea *barg2 = DatumGetByteaPP(arg2);
4142 
4143  result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
4144  len1 - VARHDRSZ) != 0);
4145 
4146  PG_FREE_IF_COPY(barg1, 0);
4147  PG_FREE_IF_COPY(barg2, 1);
4148  }
4149 
4150  PG_RETURN_BOOL(result);
4151 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define VARHDRSZ
Definition: c.h:627
#define DatumGetByteaPP(X)
Definition: fmgr.h:291
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
size_t Size
Definition: c.h:540
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 3218 of file varlena.c.

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

3219 {
3220  Datum str = PG_GETARG_DATUM(0);
3221 
3222  /* We need not detoast the input at all */
3224 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define VARHDRSZ
Definition: c.h:627
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
uintptr_t Datum
Definition: postgres.h:411

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 394 of file varlena.c.

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

Referenced by pg_mcv_list_out().

395 {
396  bytea *vlena = PG_GETARG_BYTEA_PP(0);
397  char *result;
398  char *rp;
399 
401  {
402  uint64 dstlen = pg_hex_enc_len(VARSIZE_ANY_EXHDR(vlena));
403 
404  /* Print hex format */
405  rp = result = palloc(dstlen + 2 + 1);
406  *rp++ = '\\';
407  *rp++ = 'x';
408 
409  rp += pg_hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp,
410  dstlen);
411  }
412  else if (bytea_output == BYTEA_OUTPUT_ESCAPE)
413  {
414  /* Print traditional escaped format */
415  char *vp;
416  uint64 len;
417  int i;
418 
419  len = 1; /* empty string has 1 char */
420  vp = VARDATA_ANY(vlena);
421  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
422  {
423  if (*vp == '\\')
424  len += 2;
425  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
426  len += 4;
427  else
428  len++;
429  }
430 
431  /*
432  * In principle len can't overflow uint32 if the input fit in 1GB, but
433  * for safety let's check rather than relying on palloc's internal
434  * check.
435  */
436  if (len > MaxAllocSize)
437  ereport(ERROR,
438  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
439  errmsg_internal("result of bytea output conversion is too large")));
440  rp = result = (char *) palloc(len);
441 
442  vp = VARDATA_ANY(vlena);
443  for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
444  {
445  if (*vp == '\\')
446  {
447  *rp++ = '\\';
448  *rp++ = '\\';
449  }
450  else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
451  {
452  int val; /* holds unprintable chars */
453 
454  val = *vp;
455  rp[0] = '\\';
456  rp[3] = DIG(val & 07);
457  val >>= 3;
458  rp[2] = DIG(val & 07);
459  val >>= 3;
460  rp[1] = DIG(val & 03);
461  rp += 4;
462  }
463  else
464  *rp++ = *vp;
465  }
466  }
467  else
468  {
469  elog(ERROR, "unrecognized bytea_output setting: %d",
470  bytea_output);
471  rp = result = NULL; /* keep compiler quiet */
472  }
473  *rp = '\0';
474  PG_RETURN_CSTRING(result);
475 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
uint64 pg_hex_enc_len(size_t srclen)
Definition: hex.c:175
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
int bytea_output
Definition: varlena.c:45
#define MaxAllocSize
Definition: memutils.h:40
uint64 pg_hex_encode(const char *src, size_t srclen, char *dst, size_t dstlen)
Definition: hex.c:74
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void * palloc(Size size)
Definition: mcxt.c:1062
#define elog(elevel,...)
Definition: elog.h:232
int i
Definition: c.h:621
long val
Definition: informix.c:664
#define DIG(VAL)
Definition: varlena.c:282

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 3391 of file varlena.c.

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

3392 {
3393  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3394  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3395  int sp = PG_GETARG_INT32(2); /* substring start position */
3396  int sl = PG_GETARG_INT32(3); /* substring length */
3397 
3398  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3399 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3414
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
Definition: c.h:621

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3402 of file varlena.c.

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

3403 {
3404  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3405  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3406  int sp = PG_GETARG_INT32(2); /* substring start position */
3407  int sl;
3408 
3409  sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
3410  PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3411 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3414
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 3461 of file varlena.c.

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

3462 {
3463  bytea *t1 = PG_GETARG_BYTEA_PP(0);
3464  bytea *t2 = PG_GETARG_BYTEA_PP(1);
3465  int pos;
3466  int px,
3467  p;
3468  int len1,
3469  len2;
3470  char *p1,
3471  *p2;
3472 
3473  len1 = VARSIZE_ANY_EXHDR(t1);
3474  len2 = VARSIZE_ANY_EXHDR(t2);
3475 
3476  if (len2 <= 0)
3477  PG_RETURN_INT32(1); /* result for empty pattern */
3478 
3479  p1 = VARDATA_ANY(t1);
3480  p2 = VARDATA_ANY(t2);
3481 
3482  pos = 0;
3483  px = (len1 - len2);
3484  for (p = 0; p <= px; p++)
3485  {
3486  if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
3487  {
3488  pos = p + 1;
3489  break;
3490  };
3491  p1++;
3492  };
3493 
3494  PG_RETURN_INT32(pos);
3495 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
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:308
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

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

482 {
484  bytea *result;
485  int nbytes;
486 
487  nbytes = buf->len - buf->cursor;
488  result = (bytea *) palloc(nbytes + VARHDRSZ);
489  SET_VARSIZE(result, nbytes + VARHDRSZ);
490  pq_copymsgbytes(buf, VARDATA(result), nbytes);
491  PG_RETURN_BYTEA_P(result);
492 }
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARHDRSZ
Definition: c.h:627
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static char * buf
Definition: pg_test_fsync.c:68
void pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
Definition: pqformat.c:530
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: c.h:621
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ byteasend()

Datum byteasend ( PG_FUNCTION_ARGS  )

Definition at line 500 of file varlena.c.

References PG_GETARG_BYTEA_P_COPY, and PG_RETURN_BYTEA_P.

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

501 {
502  bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
503 
504  PG_RETURN_BYTEA_P(vlena);
505 }
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
Definition: c.h:621

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 3604 of file varlena.c.

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

3605 {
3606  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3607  int64 n = PG_GETARG_INT64(1);
3608  int32 newBit = PG_GETARG_INT32(2);
3609  int len;
3610  int oldByte,
3611  newByte;
3612  int byteNo,
3613  bitNo;
3614 
3615  len = VARSIZE(res) - VARHDRSZ;
3616 
3617  if (n < 0 || n >= (int64) len * 8)
3618  ereport(ERROR,
3619  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3620  errmsg("index %lld out of valid range, 0..%lld",
3621  (long long) n, (long long) len * 8 - 1)));
3622 
3623  /* n/8 is now known < len, so safe to cast to int */
3624  byteNo = (int) (n / 8);
3625  bitNo = (int) (n % 8);
3626 
3627  /*
3628  * sanity check!
3629  */
3630  if (newBit != 0 && newBit != 1)
3631  ereport(ERROR,
3632  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3633  errmsg("new bit must be 0 or 1")));
3634 
3635  /*
3636  * Update the byte.
3637  */
3638  oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3639 
3640  if (newBit == 0)
3641  newByte = oldByte & (~(1 << bitNo));
3642  else
3643  newByte = oldByte | (1 << bitNo);
3644 
3645  ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3646 
3647  PG_RETURN_BYTEA_P(res);
3648 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARSIZE(PTR)
Definition: postgres.h:316
#define VARHDRSZ
Definition: c.h:627
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

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

3573 {
3574  bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3575  int32 n = PG_GETARG_INT32(1);
3576  int32 newByte = PG_GETARG_INT32(2);
3577  int len;
3578 
3579  len = VARSIZE(res) - VARHDRSZ;
3580 
3581  if (n < 0 || n >= len)
3582  ereport(ERROR,
3583  (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3584  errmsg("index %d out of valid range, 0..%d",
3585  n, len - 1)));
3586 
3587  /*
3588  * Now set the byte.
3589  */
3590  ((unsigned char *) VARDATA(res))[n] = newByte;
3591 
3592  PG_RETURN_BYTEA_P(res);
3593 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARSIZE(PTR)
Definition: postgres.h:316
#define VARHDRSZ
Definition: c.h:627
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:698
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621

◆ charlen_to_bytelen()

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

Definition at line 793 of file varlena.c.

References pg_database_encoding_max_length(), and pg_mblen().

Referenced by appendStringInfoRegexpSubstr(), and replace_text_regexp().

794 {
796  {
797  /* Optimization for single-byte encodings */
798  return n;
799  }
800  else
801  {
802  const char *s;
803 
804  for (s = p; n > 0; n--)
805  s += pg_mblen(s);
806 
807  return s - p;
808  }
809 }
int pg_mblen(const char *mbstr)
Definition: mbutils.c:966
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495

◆ check_collation_set()

static void check_collation_set ( Oid  collid)
static

Definition at line 1513 of file varlena.c.

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

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

1514 {
1515  if (!OidIsValid(collid))
1516  {
1517  /*
1518  * This typically means that the parser could not resolve a conflict
1519  * of implicit collations, so report it that way.
1520  */
1521  ereport(ERROR,
1522  (errcode(ERRCODE_INDETERMINATE_COLLATION),
1523  errmsg("could not determine which collation to use for string comparison"),
1524  errhint("Use the COLLATE clause to set the collation explicitly.")));
1525  }
1526 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
int errcode(int sqlerrcode)
Definition: elog.c:698
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ check_replace_text_has_escape_char()

static bool check_replace_text_has_escape_char ( const text replace_text)
static

Definition at line 4367 of file varlena.c.

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

Referenced by replace_text_regexp().

4368 {
4369  const char *p = VARDATA_ANY(replace_text);
4370  const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4371 
4373  {
4374  for (; p < p_end; p++)
4375  {
4376  if (*p == '\\')
4377  return true;
4378  }
4379  }
4380  else
4381  {
4382  for (; p < p_end; p += pg_mblen(p))
4383  {
4384  if (*p == '\\')
4385  return true;
4386  }
4387  }
4388 
4389  return false;
4390 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
int pg_mblen(const char *mbstr)
Definition: mbutils.c:966
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1495
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354

◆ concat_internal()

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

Definition at line 5489 of file varlena.c.

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

Referenced by text_concat(), and text_concat_ws().

5491 {
5492  text *result;
5494  FmgrInfo *foutcache;
5495  bool first_arg = true;
5496  int i;
5497 
5498  /*
5499  * concat(VARIADIC some-array) is essentially equivalent to
5500  * array_to_text(), ie concat the array elements with the given separator.
5501  * So we just pass the case off to that code.
5502  */
5503  if (get_fn_expr_variadic(fcinfo->flinfo))
5504  {
5505  ArrayType *arr;
5506 
5507  /* Should have just the one argument */
5508  Assert(argidx == PG_NARGS() - 1);
5509 
5510  /* concat(VARIADIC NULL) is defined as NULL */
5511  if (PG_ARGISNULL(argidx))
5512  return NULL;
5513 
5514  /*
5515  * Non-null argument had better be an array. We assume that any call
5516  * context that could let get_fn_expr_variadic return true will have
5517  * checked that a VARIADIC-labeled parameter actually is an array. So
5518  * it should be okay to just Assert that it's an array rather than
5519  * doing a full-fledged error check.
5520  */
5522 
5523  /* OK, safe to fetch the array value */
5524  arr = PG_GETARG_ARRAYTYPE_P(argidx);
5525 
5526  /*
5527  * And serialize the array. We tell array_to_text to ignore null
5528  * elements, which matches the behavior of the loop below.
5529  */
5530  return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5531  }
5532 
5533  /* Normal case without explicit VARIADIC marker */
5534  initStringInfo(&str);
5535 
5536  /* Get output function info, building it if first time through */
5537  foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5538  if (foutcache == NULL)
5539  foutcache = build_concat_foutcache(fcinfo, argidx);
5540 
5541  for (i = argidx; i < PG_NARGS(); i++)
5542  {
5543  if (!PG_ARGISNULL(i))
5544  {
5546 
5547  /* add separator if appropriate */
5548  if (first_arg)
5549  first_arg = false;
5550  else
5551  appendStringInfoString(&str, sepstr);
5552 
5553  /* call the appropriate type output function, append the result */
5555  OutputFunctionCall(&foutcache[i], value));
5556  }
5557  }
5558 
5559  result = cstring_to_text_with_len(str.data, str.len);
5560  pfree(str.data);
5561 
5562  return result;
5563 }
Definition: fmgr.h:56
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1934
#define OidIsValid(objectId)
Definition: c.h:710
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1573
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
void pfree(void *pointer)
Definition: mcxt.c:1169
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:5100
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:411
FmgrInfo * flinfo
Definition: fmgr.h:87
static struct @143 value
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:804
#define PG_NARGS()
Definition: fmgr.h:203
void * fn_extra
Definition: fmgr.h:64
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2779
int i
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5451
Definition: c.h:621

◆ cstring_to_text()

text* cstring_to_text ( const char *  s)

Definition at line 190 of file varlena.c.

References cstring_to_text_with_len().

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

191 {
192  return cstring_to_text_with_len(s, strlen(s));
193 }
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202

◆ cstring_to_text_with_len()

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

Definition at line 202 of file varlena.c.

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

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

203 {
204  text *result = (text *) palloc(len + VARHDRSZ);
205 
206  SET_VARSIZE(result, len + VARHDRSZ);
207  memcpy(VARDATA(result), s, len);
208 
209  return result;
210 }
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARHDRSZ
Definition: c.h:627
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: c.h:621
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ hexval()

static unsigned int hexval ( unsigned char  c)
static

Definition at line 6398 of file varlena.c.

References elog, and ERROR.

Referenced by hexval_n().

6399 {
6400  if (c >= '0' && c <= '9')
6401  return c - '0';
6402  if (c >= 'a' && c <= 'f')
6403  return c - 'a' + 0xA;
6404  if (c >= 'A' && c <= 'F')
6405  return c - 'A' + 0xA;
6406  elog(ERROR, "invalid hexadecimal digit");
6407  return 0; /* not reached */
6408 }
#define ERROR
Definition: elog.h:46
char * c
#define elog(elevel,...)
Definition: elog.h:232

◆ hexval_n()

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

Definition at line 6414 of file varlena.c.

References hexval(), and i.

Referenced by unistr().

6415 {
6416  unsigned int result = 0;
6417 
6418  for (size_t i = 0; i < n; i++)
6419  result += hexval(instr[i]) << (4 * (n - i - 1));
6420 
6421  return result;
6422 }
static unsigned int hexval(unsigned char c)
Definition: varlena.c:6398
int i

◆ internal_text_pattern_compare()

static int internal_text_pattern_compare ( text arg1,
text arg2 
)
static

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

3094 {
3095  int result;
3096  int len1,
3097  len2;
3098 
3099  len1 = VARSIZE_ANY_EXHDR(arg1);
3100  len2 = VARSIZE_ANY_EXHDR(arg2);
3101 
3102  result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3103  if (result != 0)
3104  return result;
3105  else if (len1 < len2)
3106  return -1;
3107  else if (len1 > len2)
3108  return 1;
3109  else
3110  return 0;
3111 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define Min(x, y)
Definition: c.h:986
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354

◆ isxdigits_n()

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

Definition at line 6388 of file varlena.c.

References i.

Referenced by unistr().

6389 {
6390  for (size_t i = 0; i < n; i++)
6391  if (!isxdigit((unsigned char) instr[i]))
6392  return false;
6393 
6394  return true;
6395 }
int i

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5379 of file varlena.c.

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

Referenced by bytea_string_agg_transfn(), and string_agg_transfn().

5380 {
5381  StringInfo state;
5382  MemoryContext aggcontext;
5383  MemoryContext oldcontext;
5384 
5385  if (!AggCheckCallContext(fcinfo, &aggcontext))
5386  {
5387  /* cannot be called directly because of internal-type argument */
5388  elog(ERROR, "string_agg_transfn called in non-aggregate context");
5389  }
5390 
5391  /*
5392  * Create state in aggregate context. It'll stay there across subsequent
5393  * calls.
5394  */
5395  oldcontext = MemoryContextSwitchTo(aggcontext);
5396  state = makeStringInfo();
5397  MemoryContextSwitchTo(oldcontext);
5398 
5399  return state;
5400 }
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define ERROR
Definition: elog.h:46
ts_parserstate state
Definition: tsquery.c:80
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4580
#define elog(elevel,...)
Definition: elog.h:232

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3678 of file varlena.c.

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

Referenced by nameiclike(), and nameicnlike().

3679 {
3680  Name s = PG_GETARG_NAME(0);
3681 
3683 }
Definition: c.h:675
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
text * cstring_to_text(const char *s)
Definition: varlena.c:190
#define NameStr(name)
Definition: c.h:681
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ nameeqtext()

Datum nameeqtext ( PG_FUNCTION_ARGS  )

Definition at line 2896 of file varlena.c.

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

2897 {
2898  Name arg1 = PG_GETARG_NAME(0);
2899  text *arg2 = PG_GETARG_TEXT_PP(1);
2900  size_t len1 = strlen(NameStr(*arg1));
2901  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2902  Oid collid = PG_GET_COLLATION();
2903  bool result;
2904 
2905  check_collation_set(collid);
2906 
2907  if (collid == C_COLLATION_OID)
2908  result = (len1 == len2 &&
2909  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2910  else
2911  result = (varstr_cmp(NameStr(*arg1), len1,
2912  VARDATA_ANY(arg2), len2,
2913  collid) == 0);
2914 
2915  PG_FREE_IF_COPY(arg2, 1);
2916 
2917  PG_RETURN_BOOL(result);
2918 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1542
static void check_collation_set(Oid collid)
Definition: varlena.c:1513
Definition: c.h:675
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
#define NameStr(name)
Definition: c.h:681
Definition: c.h:621
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ namefastcmp_c()

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

Definition at line 2259 of file varlena.c.

References DatumGetName, NAMEDATALEN, and NameStr.

Referenced by varstr_sortsupport().

2260 {
2261  Name arg1 = DatumGetName(x);
2262  Name arg2 = DatumGetName(y);
2263 
2264  return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2265 }
#define NAMEDATALEN
#define DatumGetName(X)
Definition: postgres.h:629
Definition: c.h:675
#define NameStr(name)
Definition: c.h:681

◆ namefastcmp_locale()

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

Definition at line 2302 of file varlena.c.

References DatumGetName, NameStr, and varstrfastcmp_locale().

Referenced by varstr_sortsupport().

2303 {
2304  Name arg1 = DatumGetName(x);
2305  Name arg2 = DatumGetName(y);
2306 
2307  return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)),
2308  NameStr(*arg2), strlen(NameStr(*arg2)),
2309  ssup);
2310 }
#define DatumGetName(X)
Definition: postgres.h:629
Definition: c.h:675
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2316
#define NameStr(name)
Definition: c.h:681

◆ namegetext()

Datum namegetext ( PG_FUNCTION_ARGS  )

Definition at line 3052 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

3053 {
3055 }
#define CmpCall(cmpfunc)
Definition: varlena.c:3027
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2996

◆ namegttext()

Datum namegttext ( PG_FUNCTION_ARGS  )

Definition at line 3046 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

3047 {
3049 }
#define CmpCall(cmpfunc)
Definition: varlena.c:3027
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2996

◆ nameletext()

Datum nameletext ( PG_FUNCTION_ARGS  )

Definition at line 3040 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

3041 {
3043 }
#define CmpCall(cmpfunc)
Definition: varlena.c:3027
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2996

◆ namelttext()

Datum namelttext ( PG_FUNCTION_ARGS  )

Definition at line 3034 of file varlena.c.

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

3035 {
3037 }
#define CmpCall(cmpfunc)
Definition: varlena.c:3027
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2996

◆ namenetext()

Datum namenetext ( PG_FUNCTION_ARGS  )

Definition at line 2946 of file varlena.c.

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

2947 {
2948  Name arg1 = PG_GETARG_NAME(0);
2949  text *arg2 = PG_GETARG_TEXT_PP(1);
2950  size_t len1 = strlen(NameStr(*arg1));
2951  size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2952  Oid collid = PG_GET_COLLATION();
2953  bool result;
2954 
2955  check_collation_set(collid);
2956 
2957  if (collid == C_COLLATION_OID)
2958  result = !(len1 == len2 &&
2959  memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2960  else
2961  result = !(varstr_cmp(NameStr(*arg1), len1,
2962  VARDATA_ANY(arg2), len2,
2963  collid) == 0);
2964 
2965  PG_FREE_IF_COPY(arg2, 1);
2966 
2967  PG_RETURN_BOOL(result);
2968 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1542
static void check_collation_set(Oid collid)
Definition: varlena.c:1513
Definition: c.h:675
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
#define NameStr(name)
Definition: c.h:681
Definition: c.h:621
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278

◆ pg_column_compression()

Datum pg_column_compression ( PG_FUNCTION_ARGS  )

Definition at line 5319 of file varlena.c.

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

5320 {
5321  int typlen;
5322  char *result;
5323  ToastCompressionId cmid;
5324 
5325  /* On first call, get the input type's typlen, and save at *fn_extra */
5326  if (fcinfo->flinfo->fn_extra == NULL)
5327  {
5328  /* Lookup the datatype of the supplied argument */
5329  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5330 
5331  typlen = get_typlen(argtypeid);
5332  if (typlen == 0) /* should not happen */
5333  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5334 
5335  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5336  sizeof(int));
5337  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5338  }
5339  else
5340  typlen = *((int *) fcinfo->flinfo->fn_extra);
5341 
5342  if (typlen != -1)
5343  PG_RETURN_NULL();
5344 
5345  /* get the compression method id stored in the compressed varlena */
5346  cmid = toast_get_compression_id((struct varlena *)
5348  if (cmid == TOAST_INVALID_COMPRESSION_ID)
5349  PG_RETURN_NULL();
5350 
5351  /* convert compression method id to compression method name */
5352  switch (cmid)
5353  {
5355  result = "pglz";
5356  break;
5358  result = "lz4";
5359  break;
5360  default:
5361  elog(ERROR, "invalid compression method id %d", cmid);
5362  }
5363 
5365 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
ToastCompressionId
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:46
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
text * cstring_to_text(const char *s)
Definition: varlena.c:190
#define DatumGetPointer(X)
Definition: postgres.h:593
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2144
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define elog(elevel,...)
Definition: elog.h:232
Definition: c.h:621
ToastCompressionId toast_get_compression_id(struct varlena *attr)
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

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

5273 {
5275  int32 result;
5276  int typlen;
5277 
5278  /* On first call, get the input type's typlen, and save at *fn_extra */
5279  if (fcinfo->flinfo->fn_extra == NULL)
5280  {
5281  /* Lookup the datatype of the supplied argument */
5282  Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5283 
5284  typlen = get_typlen(argtypeid);
5285  if (typlen == 0) /* should not happen */
5286  elog(ERROR, "cache lookup failed for type %u", argtypeid);
5287 
5288  fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5289  sizeof(int));
5290  *((int *) fcinfo->flinfo->fn_extra) = typlen;
5291  }
5292  else
5293  typlen = *((int *) fcinfo->flinfo->fn_extra);
5294 
5295  if (typlen == -1)
5296  {
5297  /* varlena type, possibly toasted */
5298  result = toast_datum_size(value);
5299  }
5300  else if (typlen == -2)
5301  {
5302  /* cstring */
5303  result = strlen(DatumGetCString(value)) + 1;
5304  }
5305  else
5306  {
5307  /* ordinary fixed-width type */
5308  result = typlen;
5309  }
5310 
5311  PG_RETURN_INT32(result);
5312 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
Size toast_datum_size(Datum value)
Definition: detoast.c:601
#define ERROR
Definition: elog.h:46
#define DatumGetCString(X)
Definition: postgres.h:610
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
uintptr_t Datum
Definition: postgres.h:411
static struct @143 value
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2144
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define elog(elevel,...)
Definition: elog.h:232

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

Definition at line 4292 of file varlena.c.

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

Referenced by execute_extension_script().

4293 {
4294  text *src_text = PG_GETARG_TEXT_PP(0);
4295  text *from_sub_text = PG_GETARG_TEXT_PP(1);
4296  text *to_sub_text = PG_GETARG_TEXT_PP(2);
4297  int src_text_len;
4298  int from_sub_text_len;
4300  text *ret_text;
4301  int chunk_len;
4302  char *curr_ptr;
4303  char *start_ptr;
4305  bool found;
4306 
4307  src_text_len = VARSIZE_ANY_EXHDR(src_text);
4308  from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4309 
4310  /* Return unmodified source string if empty source or pattern */
4311  if (src_text_len < 1 || from_sub_text_len < 1)
4312  {
4313  PG_RETURN_TEXT_P(src_text);
4314  }
4315 
4316  text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4317 
4318  found = text_position_next(&state);
4319 
4320  /* When the from_sub_text is not found, there is nothing to do. */
4321  if (!found)
4322  {
4323  text_position_cleanup(&state);
4324  PG_RETURN_TEXT_P(src_text);
4325  }
4326  curr_ptr = text_position_get_match_ptr(&state);
4327  start_ptr = VARDATA_ANY(src_text);
4328 
4329  initStringInfo(&str);
4330 
4331  do
4332  {
4334 
4335  /* copy the data skipped over by last text_position_next() */
4336  chunk_len = curr_ptr - start_ptr;
4337  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4338 
4339  appendStringInfoText(&str, to_sub_text);
4340 
4341  start_ptr = curr_ptr + from_sub_text_len;
4342 
4343  found = text_position_next(&state);
4344  if (found)
4345  curr_ptr = text_position_get_match_ptr(&state);
4346  }
4347  while (found);
4348 
4349  /* copy trailing data */
4350  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4351  appendBinaryStringInfo(&str, start_ptr, chunk_len);
4352 
4353  text_position_cleanup(&state);
4354 
4355  ret_text = cstring_to_text_with_len(str.data, str.len);
4356  pfree(str.data);
4357 
4358  PG_RETURN_TEXT_P(ret_text);
4359 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1331
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1463
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
void pfree(void *pointer)
Definition: mcxt.c:1169
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4278
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
ts_parserstate state
Definition: tsquery.c:80
#define VARSIZE_ANY(PTR)
Definition: postgres.h:348
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1506
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1202
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ replace_text_regexp()

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

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

4507 {
4508  text *ret_text;
4509  regex_t *re = (regex_t *) regexp;
4510  int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4513  pg_wchar *data;
4514  size_t data_len;
4515  int search_start;
4516  int data_pos;
4517  char *start_ptr;
4518  bool have_escape;
4519 
4520  initStringInfo(&buf);
4521 
4522  /* Convert data string to wide characters. */
4523  data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4524  data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4525 
4526  /* Check whether replace_text has escape char. */
4527  have_escape = check_replace_text_has_escape_char(replace_text);
4528 
4529  /* start_ptr points to the data_pos'th character of src_text */
4530  start_ptr = (char *) VARDATA_ANY(src_text);
4531  data_pos = 0;
4532 
4533  search_start = 0;
4534  while (search_start <= data_len)
4535  {
4536  int regexec_result;
4537 
4539 
4540  regexec_result = pg_regexec(re,
4541  data,
4542  data_len,
4543  search_start,
4544  NULL, /* no details */
4546  pmatch,
4547  0);
4548 
4549  if (regexec_result == REG_NOMATCH)
4550  break;
4551 
4552  if (regexec_result != REG_OKAY)
4553  {
4554  char errMsg[100];
4555 
4557  pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4558  ereport(ERROR,
4559  (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4560  errmsg("regular expression failed: %s", errMsg)));
4561  }
4562 
4563  /*
4564  * Copy the text to the left of the match position. Note we are given
4565  * character not byte indexes.
4566  */
4567  if (pmatch[0].rm_so - data_pos > 0)
4568  {
4569  int chunk_len;
4570 
4571  chunk_len = charlen_to_bytelen(start_ptr,
4572  pmatch[0].rm_so - data_pos);
4573  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4574 
4575  /*
4576  * Advance start_ptr over that text, to avoid multiple rescans of
4577  * it if the replace_text contains multiple back-references.
4578  */
4579  start_ptr += chunk_len;
4580  data_pos = pmatch[0].rm_so;
4581  }
4582 
4583  /*
4584  * Copy the replace_text. Process back references when the
4585  * replace_text has escape characters.
4586  */
4587  if (have_escape)
4588  appendStringInfoRegexpSubstr(&buf, replace_text, pmatch,
4589  start_ptr, data_pos);
4590  else
4591  appendStringInfoText(&buf, replace_text);
4592 
4593  /* Advance start_ptr and data_pos over the matched text. */
4594  start_ptr += charlen_to_bytelen(start_ptr,
4595  pmatch[0].rm_eo - data_pos);
4596  data_pos = pmatch[0].rm_eo;
4597 
4598  /*
4599  * When global option is off, replace the first instance only.
4600  */
4601  if (!glob)
4602  break;
4603 
4604  /*
4605  * Advance search position. Normally we start the next search at the
4606  * end of the previous match; but if the match was of zero length, we
4607  * have to advance by one character, or we'd just find the same match
4608  * again.
4609  */
4610  search_start = data_pos;
4611  if (pmatch[0].rm_so == pmatch[0].rm_eo)
4612  search_start++;
4613  }
4614 
4615  /*
4616  * Copy the text to the right of the last match.
4617  */
4618  if (data_pos < data_len)
4619  {
4620  int chunk_len;
4621 
4622  chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4623  appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4624  }
4625 
4626  ret_text = cstring_to_text_with_len(buf.data, buf.len);
4627  pfree(buf.data);
4628  pfree(data);
4629 
4630  return ret_text;
4631 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
regoff_t rm_so
Definition: regex.h:87
int errcode(int sqlerrcode)
Definition: elog.c:698
regoff_t rm_eo
Definition: regex.h:88
void pfree(void *pointer)
Definition: mcxt.c:1169
#define REG_OKAY
Definition: regex.h:139
#define ERROR
Definition: elog.h:46
static bool check_replace_text_has_escape_char(const text *replace_text)
Definition: varlena.c:4367
static int charlen_to_bytelen(const char *p, int n)
Definition: varlena.c:793
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4278
static char * buf
Definition: pg_test_fsync.c:68
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
unsigned int pg_wchar
Definition: mbprint.c:31
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define REGEXP_REPLACE_BACKREF_CNT
Definition: varlena.c:4494
#define VARSIZE_ANY(PTR)
Definition: postgres.h:348
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:929
#define ereport(elevel,...)
Definition: elog.h:157
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4400
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:176
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define REG_NOMATCH
Definition: regex.h:140
Definition: c.h:621
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
Definition: regex.h:55

◆ rest_of_char_same()

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

Definition at line 6219 of file varlena.c.

Referenced by varstr_levenshtein().

6220 {
6221  while (len > 0)
6222  {
6223  len--;
6224  if (s1[len] != s2[len])
6225  return false;
6226  }
6227  return true;
6228 }
char * s1
char * s2

◆ split_part()

Datum split_part ( PG_FUNCTION_ARGS  )

Definition at line 4639 of file varlena.c.

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

4640 {
4641  text *inputstring = PG_GETARG_TEXT_PP(0);
4642  text *fldsep = PG_GETARG_TEXT_PP(1);
4643  int fldnum = PG_GETARG_INT32(2);
4644  int inputstring_len;
4645  int fldsep_len;
4647  char *start_ptr;
4648  char *end_ptr;
4649  text *result_text;
4650  bool found;
4651 
4652  /* field number is 1 based */
4653  if (fldnum == 0)
4654  ereport(ERROR,
4655  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4656  errmsg("field position must not be zero")));
4657 
4658  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4659  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4660 
4661  /* return empty string for empty input string */
4662  if (inputstring_len < 1)
4664 
4665  /* handle empty field separator */
4666  if (fldsep_len < 1)
4667  {
4668  /* if first or last field, return input string, else empty string */
4669  if (fldnum == 1 || fldnum == -1)
4670  PG_RETURN_TEXT_P(inputstring);
4671  else
4673  }
4674 
4675  /* find the first field separator */
4676  text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4677 
4678  found = text_position_next(&state);
4679 
4680  /* special case if fldsep not found at all */
4681  if (!found)
4682  {
4683  text_position_cleanup(&state);
4684  /* if first or last field, return input string, else empty string */
4685  if (fldnum == 1 || fldnum == -1)
4686  PG_RETURN_TEXT_P(inputstring);
4687  else
4689  }
4690 
4691  /*
4692  * take care of a negative field number (i.e. count from the right) by
4693  * converting to a positive field number; we need total number of fields
4694  */
4695  if (fldnum < 0)
4696  {
4697  /* we found a fldsep, so there are at least two fields */
4698  int numfields = 2;
4699 
4700  while (text_position_next(&state))
4701  numfields++;
4702 
4703  /* special case of last field does not require an extra pass */
4704  if (fldnum == -1)
4705  {
4706  start_ptr = text_position_get_match_ptr(&state) + fldsep_len;
4707  end_ptr = VARDATA_ANY(inputstring) + inputstring_len;
4708  text_position_cleanup(&state);
4710  end_ptr - start_ptr));
4711  }
4712 
4713  /* else, convert fldnum to positive notation */
4714  fldnum += numfields + 1;
4715 
4716  /* if nonexistent field, return empty string */
4717  if (fldnum <= 0)
4718  {
4719  text_position_cleanup(&state);
4721  }
4722 
4723  /* reset to pointing at first match, but now with positive fldnum */
4724  text_position_reset(&state);
4725  found = text_position_next(&state);
4726  Assert(found);
4727  }
4728 
4729  /* identify bounds of first field */
4730  start_ptr = VARDATA_ANY(inputstring);
4731  end_ptr = text_position_get_match_ptr(&state);
4732 
4733  while (found && --fldnum > 0)
4734  {
4735  /* identify bounds of next field */
4736  start_ptr = end_ptr + fldsep_len;
4737  found = text_position_next(&state);
4738  if (found)
4739  end_ptr = text_position_get_match_ptr(&state);
4740  }
4741 
4742  text_position_cleanup(&state);
4743 
4744  if (fldnum > 0)
4745  {
4746  /* N'th field separator not found */
4747  /* if last field requested, return it, else empty string */
4748  if (fldnum == 1)
4749  {
4750  int last_len = start_ptr - VARDATA_ANY(inputstring);
4751 
4752  result_text = cstring_to_text_with_len(start_ptr,
4753  inputstring_len - last_len);
4754  }
4755  else
4756  result_text = cstring_to_text("");
4757  }
4758  else
4759  {
4760  /* non-last field requested */
4761  result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4762  }
4763 
4764  PG_RETURN_TEXT_P(result_text);
4765 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
static void text_position_reset(TextPositionState *state)
Definition: varlena.c:1498
int errcode(int sqlerrcode)
Definition: elog.c:698
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1331
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1463
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define ERROR
Definition: elog.h:46
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
ts_parserstate state
Definition: tsquery.c:80
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1506
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
text * cstring_to_text(const char *s)
Definition: varlena.c:190
#define Assert(condition)
Definition: c.h:804
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1202
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
int errmsg(const char *fmt,...)
Definition: elog.c:909
Definition: c.h:621

◆ split_text()

static bool split_text ( FunctionCallInfo  fcinfo,
SplitTextOutputData tstate 
)
static

Definition at line 4883 of file varlena.c.

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

Referenced by text_to_array(), and text_to_table().

4884 {
4885  text *inputstring;
4886  text *fldsep;
4887  text *null_string;
4888  Oid collation = PG_GET_COLLATION();
4889  int inputstring_len;
4890  int fldsep_len;
4891  char *start_ptr;
4892  text *result_text;
4893 
4894  /* when input string is NULL, then result is NULL too */
4895  if (PG_ARGISNULL(0))
4896  return false;
4897 
4898  inputstring = PG_GETARG_TEXT_PP(0);
4899 
4900  /* fldsep can be NULL */
4901  if (!PG_ARGISNULL(1))
4902  fldsep = PG_GETARG_TEXT_PP(1);
4903  else
4904  fldsep = NULL;
4905 
4906  /* null_string can be NULL or omitted */
4907  if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
4908  null_string = PG_GETARG_TEXT_PP(2);
4909  else
4910  null_string = NULL;
4911 
4912  if (fldsep != NULL)
4913  {
4914  /*
4915  * Normal case with non-null fldsep. Use the text_position machinery
4916  * to search for occurrences of fldsep.
4917  */
4919 
4920  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4921  fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4922 
4923  /* return empty set for empty input string */
4924  if (inputstring_len < 1)
4925  return true;
4926 
4927  /* empty field separator: return input string as a one-element set */
4928  if (fldsep_len < 1)
4929  {
4930  split_text_accum_result(tstate, inputstring,
4931  null_string, collation);
4932  return true;
4933  }
4934 
4935  text_position_setup(inputstring, fldsep, collation, &state);
4936 
4937  start_ptr = VARDATA_ANY(inputstring);
4938 
4939  for (;;)
4940  {
4941  bool found;
4942  char *end_ptr;
4943  int chunk_len;
4944 
4946 
4947  found = text_position_next(&state);
4948  if (!found)
4949  {
4950  /* fetch last field */
4951  chunk_len = ((char *) inputstring + VARSIZE_ANY(inputstring)) - start_ptr;
4952  end_ptr = NULL; /* not used, but some compilers complain */
4953  }
4954  else
4955  {
4956  /* fetch non-last field */
4957  end_ptr = text_position_get_match_ptr(&state);
4958  chunk_len = end_ptr - start_ptr;
4959  }
4960 
4961  /* build a temp text datum to pass to split_text_accum_result */
4962  result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4963 
4964  /* stash away this field */
4965  split_text_accum_result(tstate, result_text,
4966  null_string, collation);
4967 
4968  pfree(result_text);
4969 
4970  if (!found)
4971  break;
4972 
4973  start_ptr = end_ptr + fldsep_len;
4974  }
4975 
4976  text_position_cleanup(&state);
4977  }
4978  else
4979  {
4980  /*
4981  * When fldsep is NULL, each character in the input string becomes a
4982  * separate element in the result set. The separator is effectively
4983  * the space between characters.
4984  */
4985  inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4986 
4987  start_ptr = VARDATA_ANY(inputstring);
4988 
4989  while (inputstring_len > 0)
4990  {
4991  int chunk_len = pg_mblen(start_ptr);
4992 
4994 
4995  /* build a temp text datum to pass to split_text_accum_result */
4996  result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4997 
4998  /* stash away this field */
4999  split_text_accum_result(tstate, result_text,
5000  null_string, collation);
5001 
5002  pfree(result_text);
5003 
5004  start_ptr += chunk_len;
5005  inputstring_len -= chunk_len;
5006  }
5007  }
5008 
5009  return true;
5010 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1331
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1463
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
void pfree(void *pointer)
Definition: mcxt.c:1169
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
ts_parserstate state
Definition: tsquery.c:80
#define VARSIZE_ANY(PTR)
Definition: postgres.h:348
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1506
static void split_text_accum_result(SplitTextOutputData *tstate, text *field_value, text *null_string, Oid collation)
Definition: varlena.c:5019
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_NARGS()
Definition: fmgr.h:203
int pg_mblen(const char *mbstr)
Definition: mbutils.c:966
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1202
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:120

◆ split_text_accum_result()

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

Definition at line 5019 of file varlena.c.

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

Referenced by split_text().

5023 {
5024  bool is_null = false;
5025 
5026  if (null_string && text_isequal(field_value, null_string, collation))
5027  is_null = true;
5028 
5029  if (tstate->tupstore)
5030  {
5031  Datum values[1];
5032  bool nulls[1];
5033 
5034  values[0] = PointerGetDatum(field_value);
5035  nulls[0] = is_null;
5036 
5038  tstate->tupdesc,
5039  values,
5040  nulls);
5041  }
5042  else
5043  {
5044  tstate->astate = accumArrayResult(tstate->astate,
5045  PointerGetDatum(field_value),
5046  is_null,
5047  TEXTOID,
5049  }
5050 }
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, Datum *values, bool *isnull)
Definition: tuplestore.c:750
#define PointerGetDatum(X)
Definition: postgres.h:600
Tuplestorestate * tupstore
Definition: varlena.c:105
TupleDesc tupdesc
Definition: varlena.c:106
static bool text_isequal(text *txt1, text *txt2, Oid collid)
Definition: varlena.c:4771
ArrayBuildState * astate
Definition: varlena.c:104
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
uintptr_t Datum
Definition: postgres.h:411
static Datum values[MAXATTR]
Definition: bootstrap.c:166
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5087

◆ SplitDirectoriesString()

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

Definition at line 3880 of file varlena.c.

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

Referenced by load_libraries(), and PostmasterMain().

3882 {
3883  char *nextp = rawstring;
3884  bool done = false;
3885 
3886  *namelist = NIL;
3887 
3888  while (scanner_isspace(*nextp))
3889  nextp++; /* skip leading whitespace */
3890 
3891  if (*nextp == '\0')
3892  return true; /* allow empty string */
3893 
3894  /* At the top of the loop, we are at start of a new directory. */
3895  do
3896  {
3897  char *curname;
3898  char *endp;
3899 
3900  if (*nextp == '"')
3901  {
3902  /* Quoted name --- collapse quote-quote pairs */
3903  curname = nextp + 1;
3904  for (;;)
3905  {
3906  endp = strchr(nextp + 1, '"');
3907  if (endp == NULL)
3908  return false; /* mismatched quotes */
3909  if (endp[1] != '"')
3910  break; /* found end of quoted name */
3911  /* Collapse adjacent quotes into one quote, and look again */
3912  memmove(endp, endp + 1, strlen(endp));
3913  nextp = endp;
3914  }
3915  /* endp now points at the terminating quote */
3916  nextp = endp + 1;
3917  }
3918  else
3919  {
3920  /* Unquoted name --- extends to separator or end of string */
3921  curname = endp = nextp;
3922  while (*nextp && *nextp != separator)
3923  {
3924  /* trailing whitespace should not be included in name */
3925  if (!scanner_isspace(*nextp))
3926  endp = nextp + 1;
3927  nextp++;
3928  }
3929  if (curname == endp)
3930  return false; /* empty unquoted name not allowed */
3931  }
3932 
3933  while (scanner_isspace(*nextp))
3934  nextp++; /* skip trailing whitespace */
3935 
3936  if (*nextp == separator)
3937  {
3938  nextp++;
3939  while (scanner_isspace(*nextp))
3940  nextp++; /* skip leading whitespace for next */
3941  /* we expect another name, so done remains false */
3942  }
3943  else if (*nextp == '\0')
3944  done = true;
3945  else
3946  return false; /* invalid syntax */
3947 
3948  /* Now safe to overwrite separator with a null */
3949  *endp = '\0';
3950 
3951  /* Truncate path if it's overlength */
3952  if (strlen(curname) >= MAXPGPATH)
3953  curname[MAXPGPATH - 1] = '\0';
3954 
3955  /*
3956  * Finished isolating current name --- add it to list
3957  */
3958  curname = pstrdup(curname);
3959  canonicalize_path(curname);
3960  *namelist = lappend(*namelist, curname);
3961 
3962  /* Loop back if we didn't reach end of string */
3963  } while (!done);
3964 
3965  return true;
3966 }
#define NIL
Definition: pg_list.h:65
char * pstrdup(const char *in)
Definition: mcxt.c:1299
void canonicalize_path(char *path)
Definition: path.c:254
#define MAXPGPATH
List * lappend(List *list, void *datum)
Definition: list.c:336
bool scanner_isspace(char ch)
Definition: scansup.c:117

◆ SplitGUCList()

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

Definition at line 4001 of file varlena.c.

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

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

4003 {
4004  char *nextp = rawstring;
4005  bool done = false;
4006 
4007  *namelist = NIL;
4008 
4009  while (scanner_isspace(*nextp))
4010  nextp++; /* skip leading whitespace */
4011 
4012  if (*nextp == '\0')
4013  return true; /* allow empty string */
4014 
4015  /* At the top of the loop, we are at start of a new identifier. */
4016  do
4017  {
4018  char *curname;
4019  char *endp;
4020 
4021  if (*nextp == '"')
4022  {
4023  /* Quoted name --- collapse quote-quote pairs */
4024  curname = nextp + 1;
4025  for (;;)
4026  {
4027  endp = strchr(nextp + 1, '"');
4028  if (endp == NULL)
4029  return false; /* mismatched quotes */
4030  if (endp[1] != '"')
4031  break; /* found end of quoted name */
4032  /* Collapse adjacent quotes into one quote, and look again */
4033  memmove(endp, endp + 1, strlen(endp));
4034  nextp = endp;
4035  }
4036  /* endp now points at the terminating quote */
4037  nextp = endp + 1;
4038  }
4039  else
4040  {
4041  /* Unquoted name --- extends to separator or whitespace */
4042  curname = nextp;
4043  while (*nextp && *nextp != separator &&
4044  !scanner_isspace(*nextp))
4045  nextp++;
4046  endp = nextp;
4047  if (curname == nextp)
4048  return false; /* empty unquoted name not allowed */
4049  }
4050 
4051  while (scanner_isspace(*nextp))
4052  nextp++; /* skip trailing whitespace */
4053 
4054  if (*nextp == separator)
4055  {
4056  nextp++;
4057  while (scanner_isspace(*nextp))
4058  nextp++; /* skip leading whitespace for next */
4059  /* we expect another name, so done remains false */
4060  }
4061  else if (*nextp == '\0')
4062  done = true;
4063  else
4064  return false; /* invalid syntax */
4065 
4066  /* Now safe to overwrite separator with a null */
4067  *endp = '\0';
4068 
4069  /*
4070  * Finished isolating current name --- add it to list
4071  */
4072  *namelist = lappend(*namelist, curname);
4073 
4074  /* Loop back if we didn't reach end of string */
4075  } while (!done);
4076 
4077  return true;
4078 }
#define NIL
Definition: pg_list.h:65
List * lappend(List *list, void *datum)
Definition: list.c:336
bool scanner_isspace(char ch)
Definition: scansup.c:117

◆ SplitIdentifierString()

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

Definition at line 3753 of file varlena.c.

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

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

3755 {
3756  char *nextp = rawstring;
3757  bool done = false;
3758 
3759  *namelist = NIL;
3760 
3761  while (scanner_isspace(*nextp))
3762  nextp++; /* skip leading whitespace */
3763 
3764  if (*nextp == '\0')
3765  return true; /* allow empty string */
3766 
3767  /* At the top of the loop, we are at start of a new identifier. */
3768  do
3769  {
3770  char *curname;
3771  char *endp;
3772 
3773  if (*nextp == '"')
3774  {
3775  /* Quoted name --- collapse quote-quote pairs, no downcasing */
3776  curname = nextp + 1;
3777  for (;;)
3778  {
3779  endp = strchr(nextp + 1, '"');
3780  if (endp == NULL)
3781  return false; /* mismatched quotes */
3782  if (endp[1] != '"')
3783  break; /* found end of quoted name */
3784  /* Collapse adjacent quotes into one quote, and look again */
3785  memmove(endp, endp + 1, strlen(endp));
3786  nextp = endp;
3787  }
3788  /* endp now points at the terminating quote */
3789  nextp = endp + 1;
3790  }
3791  else
3792  {
3793  /* Unquoted name --- extends to separator or whitespace */
3794  char *downname;
3795  int len;
3796 
3797  curname = nextp;
3798  while (*nextp && *nextp != separator &&
3799  !scanner_isspace(*nextp))
3800  nextp++;
3801  endp = nextp;
3802  if (curname == nextp)
3803  return false; /* empty unquoted name not allowed */
3804 
3805  /*
3806  * Downcase the identifier, using same code as main lexer does.
3807  *
3808  * XXX because we want to overwrite the input in-place, we cannot
3809  * support a downcasing transformation that increases the string
3810  * length. This is not a problem given the current implementation
3811  * of downcase_truncate_identifier, but we'll probably have to do
3812  * something about this someday.
3813  */
3814  len = endp - curname;
3815  downname = downcase_truncate_identifier(curname, len, false);
3816  Assert(strlen(downname) <= len);
3817  strncpy(curname, downname, len); /* strncpy is required here */
3818  pfree(downname);
3819  }
3820 
3821  while (scanner_isspace(*nextp))
3822  nextp++; /* skip trailing whitespace */
3823 
3824  if (*nextp == separator)
3825  {
3826  nextp++;
3827  while (scanner_isspace(*nextp))
3828  nextp++; /* skip leading whitespace for next */
3829  /* we expect another name, so done remains false */
3830  }
3831  else if (*nextp == '\0')
3832  done = true;
3833  else
3834  return false; /* invalid syntax */
3835 
3836  /* Now safe to overwrite separator with a null */
3837  *endp = '\0';
3838 
3839  /* Truncate name if it's overlength */
3840  truncate_identifier(curname, strlen(curname), false);
3841 
3842  /*
3843  * Finished isolating current name --- add it to list
3844  */
3845  *namelist = lappend(*namelist, curname);
3846 
3847  /* Loop back if we didn't reach end of string */
3848  } while (!done);
3849 
3850  return true;
3851 }
#define NIL
Definition: pg_list.h:65
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:93
void pfree(void *pointer)
Definition: mcxt.c:1169
List * lappend(List *list, void *datum)
Definition: list.c:336
bool scanner_isspace(char ch)
Definition: scansup.c:117
#define Assert(condition)
Definition: c.h:804

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

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

5430 {
5431  StringInfo state;
5432 
5433  /* cannot be called directly because of internal-type argument */
5434  Assert(AggCheckCallContext(fcinfo, NULL));
5435 
5436  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5437 
5438  if (state != NULL)
5440  else
5441  PG_RETURN_NULL();
5442 }
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
ts_parserstate state
Definition: tsquery.c:80
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:804
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4580
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 5403 of file varlena.c.

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

5404 {
5405  StringInfo state;
5406 
5407  state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5408 
5409  /* Append the value unless null. */
5410  if (!PG_ARGISNULL(1))
5411  {
5412  /* On the first time through, we ignore the delimiter. */
5413  if (state == NULL)
5414  state = makeStringAggState(fcinfo);
5415  else if (!PG_ARGISNULL(2))
5416  appendStringInfoText(state, PG_GETARG_TEXT_PP(2)); /* delimiter */
5417 
5418  appendStringInfoText(state, PG_GETARG_TEXT_PP(1)); /* value */
5419  }
5420 
5421  /*
5422  * The transition type for string_agg() is declared to be "internal",
5423  * which is a pass-by-value type the same size as a pointer.
5424  */
5425  PG_RETURN_POINTER(state);
5426 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4278
ts_parserstate state
Definition: tsquery.c:80
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5379

◆ text_catenate()

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

Definition at line 752 of file varlena.c.

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

Referenced by text_overlay(), and textcat().

753 {
754  text *result;
755  int len1,
756  len2,
757  len;
758  char *ptr;
759 
760  len1 = VARSIZE_ANY_EXHDR(t1);
761  len2 = VARSIZE_ANY_EXHDR(t2);
762 
763  /* paranoia ... probably should throw error instead? */
764  if (len1 < 0)
765  len1 = 0;
766  if (len2 < 0)
767  len2 = 0;
768 
769  len = len1 + len2 + VARHDRSZ;
770  result = (text *) palloc(len);
771 
772  /* Set size of result string... */
773  SET_VARSIZE(result, len);
774 
775  /* Fill data field of result string... */
776  ptr = VARDATA(result);
777  if (len1 > 0)
778  memcpy(ptr, VARDATA_ANY(t1), len1);
779  if (len2 > 0)
780  memcpy(ptr + len1, VARDATA_ANY(t2), len2);
781 
782  return result;
783 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define VARDATA(PTR)
Definition: postgres.h:315
#define VARHDRSZ
Definition: c.h:627
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
void * palloc(Size size)
Definition: mcxt.c:1062
Definition: c.h:621
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ text_cmp()

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

Definition at line 1758 of file varlena.c.

References VARDATA_ANY, VARSIZE_ANY_EXHDR, and varstr_cmp().

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

1759 {
1760  char *a1p,
1761  *a2p;
1762  int len1,
1763  len2;
1764 
1765  a1p = VARDATA_ANY(arg1);
1766  a2p = VARDATA_ANY(arg2);
1767 
1768  len1 = VARSIZE_ANY_EXHDR(arg1);
1769  len2 = VARSIZE_ANY_EXHDR(arg2);
1770 
1771  return varstr_cmp(a1p, len1, a2p, len2, collid);
1772 }
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1542
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 5569 of file varlena.c.

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

5570 {
5571  text *result;
5572 
5573  result = concat_internal("", 0, fcinfo);
5574  if (result == NULL)
5575  PG_RETURN_NULL();
5576  PG_RETURN_TEXT_P(result);
5577 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5489
Definition: c.h:621
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5584 of file varlena.c.

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

5585 {
5586  char *sep;
5587  text *result;
5588 
5589  /* return NULL when separator is NULL */
5590  if (PG_ARGISNULL(0))
5591  PG_RETURN_NULL();
5593 
5594  result = concat_internal(sep, 1, fcinfo);
5595  if (result == NULL)
5596  PG_RETURN_NULL();
5597  PG_RETURN_TEXT_P(result);
5598 }
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5489
char * text_to_cstring(const text *t)
Definition: varlena.c:223
Definition: c.h:621
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

Definition at line 5705 of file varlena.c.

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

Referenced by text_format_nv().

5706 {
5707  text *fmt;
5709  const char *cp;
5710  const char *start_ptr;
5711  const char *end_ptr;
5712  text *result;
5713  int arg;
5714  bool funcvariadic;
5715  int nargs;
5716  Datum *elements = NULL;
5717  bool *nulls = NULL;
5718  Oid element_type = InvalidOid;
5719  Oid prev_type = InvalidOid;
5720  Oid prev_width_type = InvalidOid;
5721  FmgrInfo typoutputfinfo;
5722  FmgrInfo typoutputinfo_width;
5723 
5724  /* When format string is null, immediately return null */
5725  if (PG_ARGISNULL(0))
5726  PG_RETURN_NULL();
5727 
5728  /* If argument is marked VARIADIC, expand array into elements */
5729  if (get_fn_expr_variadic(fcinfo->flinfo))
5730  {
5731  ArrayType *arr;
5732  int16 elmlen;
5733  bool elmbyval;
5734  char elmalign;
5735  int nitems;
5736 
5737  /* Should have just the one argument */
5738  Assert(PG_NARGS() == 2);
5739 
5740  /* If argument is NULL, we treat it as zero-length array */
5741  if (PG_ARGISNULL(1))
5742  nitems = 0;
5743  else
5744  {
5745  /*
5746  * Non-null argument had better be an array. We assume that any
5747  * call context that could let get_fn_expr_variadic return true
5748  * will have checked that a VARIADIC-labeled parameter actually is
5749  * an array. So it should be okay to just Assert that it's an
5750  * array rather than doing a full-fledged error check.
5751  */
5753 
5754  /* OK, safe to fetch the array value */
5755  arr = PG_GETARG_ARRAYTYPE_P(1);
5756 
5757  /* Get info about array element type */
5758  element_type = ARR_ELEMTYPE(arr);
5759  get_typlenbyvalalign(element_type,
5760  &elmlen, &elmbyval, &elmalign);
5761 
5762  /* Extract all array elements */
5763  deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
5764  &elements, &nulls, &nitems);
5765  }
5766 
5767  nargs = nitems + 1;
5768  funcvariadic = true;
5769  }
5770  else
5771  {
5772  /* Non-variadic case, we'll process the arguments individually */
5773  nargs = PG_NARGS();
5774  funcvariadic = false;
5775  }
5776 
5777  /* Setup for main loop. */
5778  fmt = PG_GETARG_TEXT_PP(0);
5779  start_ptr = VARDATA_ANY(fmt);
5780  end_ptr = start_ptr + VARSIZE_ANY_EXHDR(fmt);
5781  initStringInfo(&str);
5782  arg = 1; /* next argument position to print */
5783 
5784  /* Scan format string, looking for conversion specifiers. */
5785  for (cp = start_ptr; cp < end_ptr; cp++)
5786  {
5787  int argpos;
5788  int widthpos;
5789  int flags;
5790  int width;
5791  Datum value;
5792  bool isNull;
5793  Oid typid;
5794 
5795  /*
5796  * If it's not the start of a conversion specifier, just copy it to
5797  * the output buffer.
5798  */
5799  if (*cp != '%')
5800  {
5801  appendStringInfoCharMacro(&str, *cp);
5802  continue;
5803  }
5804 
5805  ADVANCE_PARSE_POINTER(cp, end_ptr);
5806 
5807  /* Easy case: %% outputs a single % */
5808  if (*cp == '%')
5809  {
5810  appendStringInfoCharMacro(&str, *cp);
5811  continue;
5812  }
5813 
5814  /* Parse the optional portions of the format specifier */
5815  cp = text_format_parse_format(cp, end_ptr,
5816  &argpos, &widthpos,
5817  &flags, &width);
5818 
5819  /*
5820  * Next we should see the main conversion specifier. Whether or not
5821  * an argument position was present, it's known that at least one
5822  * character remains in the string at this point. Experience suggests
5823  * that it's worth checking that that character is one of the expected
5824  * ones before we try to fetch arguments, so as to produce the least
5825  * confusing response to a mis-formatted specifier.
5826  */
5827  if (strchr("sIL", *cp) == NULL)
5828  ereport(ERROR,
5829  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5830  errmsg("unrecognized format() type specifier \"%.*s\"",
5831  pg_mblen(cp), cp),
5832  errhint("For a single \"%%\" use \"%%%%\".")));
5833 
5834  /* If indirect width was specified, get its value */
5835  if (widthpos >= 0)
5836  {
5837  /* Collect the specified or next argument position */
5838  if (widthpos > 0)
5839  arg = widthpos;
5840  if (arg >= nargs)
5841  ereport(ERROR,
5842  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5843  errmsg("too few arguments for format()")));
5844 
5845  /* Get the value and type of the selected argument */
5846  if (!funcvariadic)
5847  {
5848  value = PG_GETARG_DATUM(arg);
5849  isNull = PG_ARGISNULL(arg);
5850  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5851  }
5852  else
5853  {
5854  value = elements[arg - 1];
5855  isNull = nulls[arg - 1];
5856  typid = element_type;
5857  }
5858  if (!OidIsValid(typid))
5859  elog(ERROR, "could not determine data type of format() input");
5860 
5861  arg++;
5862 
5863  /* We can treat NULL width the same as zero */
5864  if (isNull)
5865  width = 0;
5866  else if (typid == INT4OID)
5867  width = DatumGetInt32(value);
5868  else if (typid == INT2OID)
5869  width = DatumGetInt16(value);
5870  else
5871  {
5872  /* For less-usual datatypes, convert to text then to int */
5873  char *str;
5874 
5875  if (typid != prev_width_type)
5876  {
5877  Oid typoutputfunc;
5878  bool typIsVarlena;
5879 
5880  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5881  fmgr_info(typoutputfunc, &typoutputinfo_width);
5882  prev_width_type = typid;
5883  }
5884 
5885  str = OutputFunctionCall(&typoutputinfo_width, value);
5886 
5887  /* pg_strtoint32 will complain about bad data or overflow */
5888  width = pg_strtoint32(str);
5889 
5890  pfree(str);
5891  }
5892  }
5893 
5894  /* Collect the specified or next argument position */
5895  if (argpos > 0)
5896  arg = argpos;
5897  if (arg >= nargs)
5898  ereport(ERROR,
5899  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5900  errmsg("too few arguments for format()")));
5901 
5902  /* Get the value and type of the selected argument */
5903  if (!funcvariadic)
5904  {
5905  value = PG_GETARG_DATUM(arg);
5906  isNull = PG_ARGISNULL(arg);
5907  typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5908  }
5909  else
5910  {
5911  value = elements[arg - 1];
5912  isNull = nulls[arg - 1];
5913  typid = element_type;
5914  }
5915  if (!OidIsValid(typid))
5916  elog(ERROR, "could not determine data type of format() input");
5917 
5918  arg++;
5919 
5920  /*
5921  * Get the appropriate typOutput function, reusing previous one if
5922  * same type as previous argument. That's particularly useful in the
5923  * variadic-array case, but often saves work even for ordinary calls.
5924  */
5925  if (typid != prev_type)
5926  {
5927  Oid typoutputfunc;
5928  bool typIsVarlena;
5929 
5930  getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
5931  fmgr_info(typoutputfunc, &typoutputfinfo);
5932  prev_type = typid;
5933  }
5934 
5935  /*
5936  * And now we can format the value.
5937  */
5938  switch (*cp)
5939  {
5940  case 's':
5941  case 'I':
5942  case 'L':
5943  text_format_string_conversion(&str, *cp, &typoutputfinfo,
5944  value, isNull,
5945  flags, width);
5946  break;
5947  default:
5948  /* should not get here, because of previous check */
5949  ereport(ERROR,
5950  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5951  errmsg("unrecognized format() type specifier \"%.*s\"",
5952  pg_mblen(cp), cp),
5953  errhint("For a single \"%%\" use \"%%%%\".")));
5954  break;
5955  }
5956  }
5957 
5958  /* Don't need deconstruct_array results anymore. */
5959  if (elements != NULL)
5960  pfree(elements);
5961  if (nulls != NULL)
5962  pfree(nulls);
5963 
5964  /* Generate results. */
5965  result = cstring_to_text_with_len(str.data, str.len);
5966  pfree(str.data);
5967 
5968  PG_RETURN_TEXT_P(result);
5969 }
signed short int16
Definition: c.h:428
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5692
Definition: fmgr.h:56
int errhint(const char *fmt,...)
Definition: elog.c:1156
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define DatumGetInt32(X)
Definition: postgres.h:516
static void text_format_string_conversion(StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
Definition: varlena.c:6108
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2218
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:1934
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1573
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:128
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:126
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
#define DatumGetInt16(X)
Definition: postgres.h:488
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:411
#define InvalidOid
Definition: postgres_ext.h:36
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define Assert(condition)
Definition: c.h:804
#define PG_NARGS()
Definition: fmgr.h:203
int pg_mblen(const char *mbstr)
Definition: mbutils.c:966
int32 pg_strtoint32(const char *s)
Definition: numutils.c:263
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3490
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2779
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
void * arg
Definition: c.h:621
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:6031
#define ARR_ELEMTYPE(a)
Definition: array.h:285
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ text_format_append_string()

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

Definition at line 6157 of file varlena.c.

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

Referenced by text_format_string_conversion().

6159 {
6160  bool align_to_left = false;
6161  int len;
6162 
6163  /* fast path for typical easy case */
6164  if (width == 0)
6165  {
6167  return;
6168  }
6169 
6170  if (width < 0)
6171  {
6172  /* Negative width: implicit '-' flag, then take absolute value */
6173  align_to_left = true;
6174  /* -INT_MIN is undefined */
6175  if (width <= INT_MIN)
6176  ereport(ERROR,
6177  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6178  errmsg("number is out of range")));
6179  width = -width;
6180  }
6181  else if (flags & TEXT_FORMAT_FLAG_MINUS)
6182  align_to_left = true;
6183 
6184  len = pg_mbstrlen(str);
6185  if (align_to_left)
6186  {
6187  /* left justify */
6189  if (len < width)
6190  appendStringInfoSpaces(buf, width - len);
6191  }
6192  else
6193  {
6194  /* right justify */
6195  if (len < width)
6196  appendStringInfoSpaces(buf, width - len);
6198  }
6199 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:206
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:980
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5690

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 6209 of file varlena.c.

References text_format().

6210 {
6211  return text_format(fcinfo);
6212 }
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5705

◆ text_format_parse_digits()

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

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

5983 {
5984  bool found = false;
5985  const char *cp = *ptr;
5986  int val = 0;
5987 
5988  while (*cp >= '0' && *cp <= '9')
5989  {
5990  int8 digit = (*cp - '0');
5991 
5992  if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
5993  unlikely(pg_add_s32_overflow(val, digit, &val)))
5994  ereport(ERROR,
5995  (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
5996  errmsg("number is out of range")));
5997  ADVANCE_PARSE_POINTER(cp, end_ptr);
5998  found = true;
5999  }
6000 
6001  *ptr = cp;
6002  *value = val;
6003 
6004  return found;
6005 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5692
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:140
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
signed char int8
Definition: c.h:427
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:157
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:104
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define unlikely(x)
Definition: c.h:273
long val
Definition: informix.c:664

◆ text_format_parse_format()

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

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

6034 {
6035  const char *cp = start_ptr;
6036  int n;
6037 
6038  /* set defaults for output parameters */
6039  *argpos = -1;
6040  *widthpos = -1;
6041  *flags = 0;
6042  *width = 0;
6043 
6044  /* try to identify first number */
6045  if (text_format_parse_digits(&cp, end_ptr, &n))
6046  {
6047  if (*cp != '$')
6048  {
6049  /* Must be just a width and a type, so we're done */
6050  *width = n;
6051  return cp;
6052  }
6053  /* The number was argument position */
6054  *argpos = n;
6055  /* Explicit 0 for argument index is immediately refused */
6056  if (n == 0)
6057  ereport(ERROR,
6058  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6059  errmsg("format specifies argument 0, but arguments are numbered from 1")));
6060  ADVANCE_PARSE_POINTER(cp, end_ptr);
6061  }
6062 
6063  /* Handle flags (only minus is supported now) */
6064  while (*cp == '-')
6065  {
6066  *flags |= TEXT_FORMAT_FLAG_MINUS;
6067  ADVANCE_PARSE_POINTER(cp, end_ptr);
6068  }
6069 
6070  if (*cp == '*')
6071  {
6072  /* Handle indirect width */
6073  ADVANCE_PARSE_POINTER(cp, end_ptr);
6074  if (text_format_parse_digits(&cp, end_ptr, &n))
6075  {
6076  /* number in this position must be closed by $ */
6077  if (*cp != '$')
6078  ereport(ERROR,
6079  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6080  errmsg("width argument position must be ended by \"$\"")));
6081  /* The number was width argument position */
6082  *widthpos = n;
6083  /* Explicit 0 for argument index is immediately refused */
6084  if (n == 0)
6085  ereport(ERROR,
6086  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6087  errmsg("format specifies argument 0, but arguments are numbered from 1")));
6088  ADVANCE_PARSE_POINTER(cp, end_ptr);
6089  }
6090  else
6091  *widthpos = 0; /* width's argument position is unspecified */
6092  }
6093  else
6094  {
6095  /* Check for direct width specification */
6096  if (text_format_parse_digits(&cp, end_ptr, &n))
6097  *width = n;
6098  }
6099 
6100  /* cp should now be pointing at type character */
6101  return cp;
6102 }
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5692
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:5982
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5690

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

6112 {
6113  char *str;
6114 
6115  /* Handle NULL arguments before trying to stringify the value. */
6116  if (isNull)
6117  {
6118  if (conversion == 's')
6119  text_format_append_string(buf, "", flags, width);
6120  else if (conversion == 'L')
6121  text_format_append_string(buf, "NULL", flags, width);
6122  else if (conversion == 'I')
6123  ereport(ERROR,
6124  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6125  errmsg("null values cannot be formatted as an SQL identifier")));
6126  return;
6127  }
6128 
6129  /* Stringify. */
6130  str = OutputFunctionCall(typOutputInfo, value);
6131 
6132  /* Escape. */
6133  if (conversion == 'I')
6134  {
6135  /* quote_identifier may or may not allocate a new string. */
6136  text_format_append_string(buf, quote_identifier(str), flags, width);
6137  }
6138  else if (conversion == 'L')
6139  {
6140  char *qstr = quote_literal_cstr(str);
6141 
6142  text_format_append_string(buf, qstr, flags, width);
6143  /* quote_literal_cstr() always allocates a new string */
6144  pfree(qstr);
6145  }
6146  else
6147  text_format_append_string(buf, str, flags, width);
6148 
6149  /* Cleanup. */
6150  pfree(str);
6151 }
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:102
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11332
int errcode(int sqlerrcode)
Definition: elog.c:698
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:6157
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1573
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
static struct @143 value
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

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

1931 {
1932  text *arg1 = PG_GETARG_TEXT_PP(0);
1933  text *arg2 = PG_GETARG_TEXT_PP(1);
1934  bool result;
1935 
1936  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1937 
1938  PG_FREE_IF_COPY(arg1, 0);
1939  PG_FREE_IF_COPY(arg2, 1);
1940 
1941  PG_RETURN_BOOL(result);
1942 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1758
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

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

1916 {
1917  text *arg1 = PG_GETARG_TEXT_PP(0);
1918  text *arg2 = PG_GETARG_TEXT_PP(1);
1919  bool result;
1920 
1921  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1922 
1923  PG_FREE_IF_COPY(arg1, 0);
1924  PG_FREE_IF_COPY(arg2, 1);
1925 
1926  PG_RETURN_BOOL(result);
1927 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1758
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ text_isequal()

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

Definition at line 4771 of file varlena.c.

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

Referenced by split_text_accum_result().

4772 {
4774  collid,
4775  PointerGetDatum(txt1),
4776  PointerGetDatum(txt2)));
4777 }
#define PointerGetDatum(X)
Definition: postgres.h:600
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1783
#define DatumGetBool(X)
Definition: postgres.h:437
Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:811

◆ text_larger()

Datum text_larger ( PG_FUNCTION_ARGS  )

Definition at line 2867 of file varlena.c.

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

2868 {
2869  text *arg1 = PG_GETARG_TEXT_PP(0);
2870  text *arg2 = PG_GETARG_TEXT_PP(1);
2871  text *result;
2872 
2873  result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2874 
2875  PG_RETURN_TEXT_P(result);
2876 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1758
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
Definition: c.h:621

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

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

1901 {
1902  text *arg1 = PG_GETARG_TEXT_PP(0);
1903  text *arg2 = PG_GETARG_TEXT_PP(1);
1904  bool result;
1905 
1906  result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1907 
1908  PG_FREE_IF_COPY(arg1, 0);
1909  PG_FREE_IF_COPY(arg2, 1);
1910 
1911  PG_RETURN_BOOL(result);
1912 }
#define PG_GET_COLLATION()
Definition: fmgr.h:198
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1758
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
Definition: c.h:621

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

Definition at line 5605 of file varlena.c.

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

5606 {
5607  int n = PG_GETARG_INT32(1);
5608 
5609  if (n < 0)
5610  {
5611  text *str = PG_GETARG_TEXT_PP(0);
5612  const char *p = VARDATA_ANY(str);
5613  int len = VARSIZE_ANY_EXHDR(str);
5614  int rlen;
5615 
5616  n = pg_mbstrlen_with_len(p, len) + n;
5617  rlen = pg_mbcharcliplen(p, len, n);
5619  }
5620  else
5622 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1068
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:1000
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:872
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:202
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354
Definition: c.h:621
</