PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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/int.h"
#include "common/unicode_category.h"
#include "common/unicode_norm.h"
#include "common/unicode_version.h"
#include "funcapi.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/guc.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 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 TEXT_FORMAT_FLAG_MINUS   0x0001 /* is minus flag present? */
 
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
 
#define LEVENSHTEIN_LESS_EQUAL
 

Typedefs

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 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 bytea_reverse (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_larger (PG_FUNCTION_ARGS)
 
Datum bytea_smaller (PG_FUNCTION_ARGS)
 
Datum bytea_sortsupport (PG_FUNCTION_ARGS)
 
Datum bytea_int2 (PG_FUNCTION_ARGS)
 
Datum bytea_int4 (PG_FUNCTION_ARGS)
 
Datum bytea_int8 (PG_FUNCTION_ARGS)
 
Datum int2_bytea (PG_FUNCTION_ARGS)
 
Datum int4_bytea (PG_FUNCTION_ARGS)
 
Datum int8_bytea (PG_FUNCTION_ARGS)
 
Datum replace_text (PG_FUNCTION_ARGS)
 
static int check_replace_text_has_escape (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, text *pattern_text, text *replace_text, int cflags, Oid collation, int search_start, int n)
 
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)
 
static textconvert_to_base (uint64 value, int base)
 
Datum to_bin32 (PG_FUNCTION_ARGS)
 
Datum to_bin64 (PG_FUNCTION_ARGS)
 
Datum to_oct32 (PG_FUNCTION_ARGS)
 
Datum to_oct64 (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 pg_column_toast_chunk_id (PG_FUNCTION_ARGS)
 
Datum string_agg_transfn (PG_FUNCTION_ARGS)
 
Datum string_agg_combine (PG_FUNCTION_ARGS)
 
Datum string_agg_serialize (PG_FUNCTION_ARGS)
 
Datum string_agg_deserialize (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)
 
void initClosestMatch (ClosestMatchState *state, const char *source, int max_d)
 
void updateClosestMatch (ClosestMatchState *state, const char *candidate)
 
const char * getClosestMatch (ClosestMatchState *state)
 
static UnicodeNormalizationForm unicode_norm_form_from_string (const char *formstr)
 
Datum unicode_version (PG_FUNCTION_ARGS)
 
Datum icu_unicode_version (PG_FUNCTION_ARGS)
 
Datum unicode_assigned (PG_FUNCTION_ARGS)
 
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:1317
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39

Definition at line 5827 of file varlena.c.

◆ CmpCall

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

Definition at line 2778 of file varlena.c.

◆ DatumGetVarStringP

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

Definition at line 124 of file varlena.c.

◆ DatumGetVarStringPP

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

Definition at line 125 of file varlena.c.

◆ DIG

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

Definition at line 284 of file varlena.c.

◆ LEVENSHTEIN_LESS_EQUAL

#define LEVENSHTEIN_LESS_EQUAL

Definition at line 6367 of file varlena.c.

◆ PG_STR_GET_BYTEA

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

Definition at line 3033 of file varlena.c.

◆ TEXT_FORMAT_FLAG_MINUS

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

Definition at line 5825 of file varlena.c.

◆ TEXTBUFLEN

#define TEXTBUFLEN   1024

Definition at line 122 of file varlena.c.

◆ VAL

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

Definition at line 283 of file varlena.c.

Typedef Documentation

◆ VarString

typedef struct varlena VarString

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

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

References appendBinaryStringInfo(), appendStringInfoChar(), Assert(), charlen_to_bytelen(), idx(), replace_text(), str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text_regexp().

◆ appendStringInfoText()

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

◆ array_to_text()

Datum array_to_text ( PG_FUNCTION_ARGS  )

Definition at line 4968 of file varlena.c.

4969{
4971 char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4972
4973 PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4974}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
static text * array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string)
Definition: varlena.c:5010
char * text_to_cstring(const text *t)
Definition: varlena.c:225

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

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

5012{
5013 text *result;
5014 int nitems,
5015 *dims,
5016 ndims;
5017 Oid element_type;
5018 int typlen;
5019 bool typbyval;
5020 char typalign;
5022 bool printed = false;
5023 char *p;
5024 bits8 *bitmap;
5025 int bitmask;
5026 int i;
5027 ArrayMetaState *my_extra;
5028
5029 ndims = ARR_NDIM(v);
5030 dims = ARR_DIMS(v);
5031 nitems = ArrayGetNItems(ndims, dims);
5032
5033 /* if there are no elements, return an empty string */
5034 if (nitems == 0)
5035 return cstring_to_text_with_len("", 0);
5036
5037 element_type = ARR_ELEMTYPE(v);
5039
5040 /*
5041 * We arrange to look up info about element type, including its output
5042 * conversion proc, only once per series of calls, assuming the element
5043 * type doesn't change underneath us.
5044 */
5045 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
5046 if (my_extra == NULL)
5047 {
5048 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5049 sizeof(ArrayMetaState));
5050 my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
5051 my_extra->element_type = ~element_type;
5052 }
5053
5054 if (my_extra->element_type != element_type)
5055 {
5056 /*
5057 * Get info about element type, including its output conversion proc
5058 */
5059 get_type_io_data(element_type, IOFunc_output,
5060 &my_extra->typlen, &my_extra->typbyval,
5061 &my_extra->typalign, &my_extra->typdelim,
5062 &my_extra->typioparam, &my_extra->typiofunc);
5063 fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,
5064 fcinfo->flinfo->fn_mcxt);
5065 my_extra->element_type = element_type;
5066 }
5067 typlen = my_extra->typlen;
5068 typbyval = my_extra->typbyval;
5069 typalign = my_extra->typalign;
5070
5071 p = ARR_DATA_PTR(v);
5072 bitmap = ARR_NULLBITMAP(v);
5073 bitmask = 1;
5074
5075 for (i = 0; i < nitems; i++)
5076 {
5077 Datum itemvalue;
5078 char *value;
5079
5080 /* Get source element, checking for NULL */
5081 if (bitmap && (*bitmap & bitmask) == 0)
5082 {
5083 /* if null_string is NULL, we just ignore null elements */
5084 if (null_string != NULL)
5085 {
5086 if (printed)
5087 appendStringInfo(&buf, "%s%s", fldsep, null_string);
5088 else
5089 appendStringInfoString(&buf, null_string);
5090 printed = true;
5091 }
5092 }
5093 else
5094 {
5095 itemvalue = fetch_att(p, typbyval, typlen);
5096
5097 value = OutputFunctionCall(&my_extra->proc, itemvalue);
5098
5099 if (printed)
5100 appendStringInfo(&buf, "%s%s", fldsep, value);
5101 else
5103 printed = true;
5104
5105 p = att_addlength_pointer(p, typlen, p);
5106 p = (char *) att_align_nominal(p, typalign);
5107 }
5108
5109 /* advance bitmap pointer if any */
5110 if (bitmap)
5111 {
5112 bitmask <<= 1;
5113 if (bitmask == 0x100)
5114 {
5115 bitmap++;
5116 bitmask = 1;
5117 }
5118 }
5119 }
5120
5121 result = cstring_to_text_with_len(buf.data, buf.len);
5122 pfree(buf.data);
5123
5124 return result;
5125}
#define ARR_NDIM(a)
Definition: array.h:290
#define ARR_DATA_PTR(a)
Definition: array.h:322
#define ARR_NULLBITMAP(a)
Definition: array.h:300
#define ARR_ELEMTYPE(a)
Definition: array.h:292
#define ARR_DIMS(a)
Definition: array.h:294
int ArrayGetNItems(int ndim, const int *dims)
Definition: arrayutils.c:57
uint8 bits8
Definition: c.h:509
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:137
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1683
#define nitems(x)
Definition: indent.h:31
static struct @165 value
int i
Definition: isn.c:77
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
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:2408
@ IOFunc_output
Definition: lsyscache.h:37
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
void pfree(void *pointer)
Definition: mcxt.c:1524
static char * buf
Definition: pg_test_fsync.c:72
char typalign
Definition: pg_type.h:176
uintptr_t Datum
Definition: postgres.h:69
unsigned int Oid
Definition: postgres_ext.h:30
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
Oid typioparam
Definition: array.h:243
char typalign
Definition: array.h:241
Oid typiofunc
Definition: array.h:244
int16 typlen
Definition: array.h:239
Oid element_type
Definition: array.h:238
FmgrInfo proc
Definition: array.h:245
char typdelim
Definition: array.h:242
bool typbyval
Definition: array.h:240
void * fn_extra
Definition: fmgr.h:64
MemoryContext fn_mcxt
Definition: fmgr.h:65
FmgrInfo * flinfo
Definition: fmgr.h:87
Definition: c.h:658
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:150
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:185
static Datum fetch_att(const void *T, bool attbyval, int attlen)
Definition: tupmacs.h:53
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:204

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

◆ array_to_text_null()

Datum array_to_text_null ( PG_FUNCTION_ARGS  )

Definition at line 4984 of file varlena.c.

4985{
4986 ArrayType *v;
4987 char *fldsep;
4988 char *null_string;
4989
4990 /* returns NULL when first or second parameter is NULL */
4991 if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4993
4994 v = PG_GETARG_ARRAYTYPE_P(0);
4996
4997 /* NULL null string is passed through as a null pointer */
4998 if (!PG_ARGISNULL(2))
4999 null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
5000 else
5001 null_string = NULL;
5002
5003 PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
5004}
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_RETURN_NULL()
Definition: fmgr.h:345

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

◆ bpcharfastcmp_c()

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

Definition at line 2102 of file varlena.c.

2103{
2104 BpChar *arg1 = DatumGetBpCharPP(x);
2105 BpChar *arg2 = DatumGetBpCharPP(y);
2106 char *a1p,
2107 *a2p;
2108 int len1,
2109 len2,
2110 result;
2111
2112 a1p = VARDATA_ANY(arg1);
2113 a2p = VARDATA_ANY(arg2);
2114
2115 len1 = bpchartruelen(a1p, VARSIZE_ANY_EXHDR(arg1));
2116 len2 = bpchartruelen(a2p, VARSIZE_ANY_EXHDR(arg2));
2117
2118 result = memcmp(a1p, a2p, Min(len1, len2));
2119 if ((result == 0) && (len1 != len2))
2120 result = (len1 < len2) ? -1 : 1;
2121
2122 /* We can't afford to leak memory here. */
2123 if (PointerGetDatum(arg1) != x)
2124 pfree(arg1);
2125 if (PointerGetDatum(arg2) != y)
2126 pfree(arg2);
2127
2128 return result;
2129}
#define Min(x, y)
Definition: c.h:975
#define DatumGetBpCharPP(X)
Definition: fmgr.h:293
int y
Definition: isn.c:76
int x
Definition: isn.c:75
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
int bpchartruelen(char *s, int len)
Definition: varchar.c:676

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

Referenced by varstr_sortsupport().

◆ btnametextcmp()

Datum btnametextcmp ( PG_FUNCTION_ARGS  )

Definition at line 2747 of file varlena.c.

2748{
2749 Name arg1 = PG_GETARG_NAME(0);
2750 text *arg2 = PG_GETARG_TEXT_PP(1);
2751 int32 result;
2752
2753 result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)),
2754 VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2),
2756
2757 PG_FREE_IF_COPY(arg2, 1);
2758
2759 PG_RETURN_INT32(result);
2760}
#define NameStr(name)
Definition: c.h:717
int32_t int32
Definition: c.h:498
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_NAME(n)
Definition: fmgr.h:278
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
Definition: c.h:712
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition: varlena.c:1610

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

◆ bttext_pattern_cmp()

Datum bttext_pattern_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2930 of file varlena.c.

2931{
2932 text *arg1 = PG_GETARG_TEXT_PP(0);
2933 text *arg2 = PG_GETARG_TEXT_PP(1);
2934 int result;
2935
2936 result = internal_text_pattern_compare(arg1, arg2);
2937
2938 PG_FREE_IF_COPY(arg1, 0);
2939 PG_FREE_IF_COPY(arg2, 1);
2940
2941 PG_RETURN_INT32(result);
2942}
static int internal_text_pattern_compare(text *arg1, text *arg2)
Definition: varlena.c:2844

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

◆ bttext_pattern_sortsupport()

Datum bttext_pattern_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 2946 of file varlena.c.

2947{
2949 MemoryContext oldcontext;
2950
2951 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
2952
2953 /* Use generic string SortSupport, forcing "C" collation */
2954 varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID);
2955
2956 MemoryContextSwitchTo(oldcontext);
2957
2959}
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
MemoryContext ssup_cxt
Definition: sortsupport.h:66
void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid)
Definition: varlena.c:1928

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

◆ bttextcmp()

Datum bttextcmp ( PG_FUNCTION_ARGS  )

Definition at line 1886 of file varlena.c.

1887{
1888 text *arg1 = PG_GETARG_TEXT_PP(0);
1889 text *arg2 = PG_GETARG_TEXT_PP(1);
1890 int32 result;
1891
1892 result = text_cmp(arg1, arg2, PG_GET_COLLATION());
1893
1894 PG_FREE_IF_COPY(arg1, 0);
1895 PG_FREE_IF_COPY(arg2, 1);
1896
1897 PG_RETURN_INT32(result);
1898}
static int text_cmp(text *arg1, text *arg2, Oid collid)
Definition: varlena.c:1658

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

Referenced by gbt_textcmp().

◆ bttextnamecmp()

Datum bttextnamecmp ( PG_FUNCTION_ARGS  )

Definition at line 2763 of file varlena.c.

2764{
2765 text *arg1 = PG_GETARG_TEXT_PP(0);
2766 Name arg2 = PG_GETARG_NAME(1);
2767 int32 result;
2768
2769 result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1),
2770 NameStr(*arg2), strlen(NameStr(*arg2)),
2772
2773 PG_FREE_IF_COPY(arg1, 0);
2774
2775 PG_RETURN_INT32(result);
2776}

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

◆ bttextsortsupport()

Datum bttextsortsupport ( PG_FUNCTION_ARGS  )

Definition at line 1901 of file varlena.c.

1902{
1904 Oid collid = ssup->ssup_collation;
1905 MemoryContext oldcontext;
1906
1907 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
1908
1909 /* Use generic string SortSupport */
1910 varstr_sortsupport(ssup, TEXTOID, collid);
1911
1912 MemoryContextSwitchTo(oldcontext);
1913
1915}
Oid collid

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

◆ btvarstrequalimage()

Datum btvarstrequalimage ( PG_FUNCTION_ARGS  )

Definition at line 2604 of file varlena.c.

2605{
2606 /* Oid opcintype = PG_GETARG_OID(0); */
2609
2611
2613
2614 PG_RETURN_BOOL(locale->deterministic);
2615}
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static char * locale
Definition: initdb.c:140
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1188
static void check_collation_set(Oid collid)
Definition: varlena.c:1581

References check_collation_set(), collid, locale, PG_GET_COLLATION, pg_newlocale_from_collation(), and PG_RETURN_BOOL.

◆ build_concat_foutcache()

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

Definition at line 5586 of file varlena.c.

5587{
5588 FmgrInfo *foutcache;
5589 int i;
5590
5591 /* We keep the info in fn_mcxt so it survives across calls */
5592 foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5593 PG_NARGS() * sizeof(FmgrInfo));
5594
5595 for (i = argidx; i < PG_NARGS(); i++)
5596 {
5597 Oid valtype;
5598 Oid typOutput;
5599 bool typIsVarlena;
5600
5601 valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5602 if (!OidIsValid(valtype))
5603 elog(ERROR, "could not determine data type of concat() input");
5604
5605 getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5606 fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5607 }
5608
5609 fcinfo->flinfo->fn_extra = foutcache;
5610
5611 return foutcache;
5612}
#define OidIsValid(objectId)
Definition: c.h:746
#define elog(elevel,...)
Definition: elog.h:225
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1910
struct FmgrInfo FmgrInfo
#define PG_NARGS()
Definition: fmgr.h:203
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2990
Definition: fmgr.h:57

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

◆ bytea_bit_count()

Datum bytea_bit_count ( PG_FUNCTION_ARGS  )

Definition at line 3198 of file varlena.c.

3199{
3200 bytea *t1 = PG_GETARG_BYTEA_PP(0);
3201
3203}
#define PG_GETARG_BYTEA_PP(n)
Definition: fmgr.h:308
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
static uint64 pg_popcount(const char *buf, int bytes)
Definition: pg_bitutils.h:363

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

◆ bytea_catenate()

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

Definition at line 3000 of file varlena.c.

3001{
3002 bytea *result;
3003 int len1,
3004 len2,
3005 len;
3006 char *ptr;
3007
3008 len1 = VARSIZE_ANY_EXHDR(t1);
3009 len2 = VARSIZE_ANY_EXHDR(t2);
3010
3011 /* paranoia ... probably should throw error instead? */
3012 if (len1 < 0)
3013 len1 = 0;
3014 if (len2 < 0)
3015 len2 = 0;
3016
3017 len = len1 + len2 + VARHDRSZ;
3018 result = (bytea *) palloc(len);
3019
3020 /* Set size of result string... */
3021 SET_VARSIZE(result, len);
3022
3023 /* Fill data field of result string... */
3024 ptr = VARDATA(result);
3025 if (len1 > 0)
3026 memcpy(ptr, VARDATA_ANY(t1), len1);
3027 if (len2 > 0)
3028 memcpy(ptr + len1, VARDATA_ANY(t2), len2);
3029
3030 return result;
3031}
#define VARHDRSZ
Definition: c.h:663
void * palloc(Size size)
Definition: mcxt.c:1317
const void size_t len
#define VARDATA(PTR)
Definition: varatt.h:278
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

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

Referenced by bytea_overlay(), and byteacat().

◆ bytea_int2()

Datum bytea_int2 ( PG_FUNCTION_ARGS  )

Definition at line 4083 of file varlena.c.

4084{
4085 bytea *v = PG_GETARG_BYTEA_PP(0);
4086 int len = VARSIZE_ANY_EXHDR(v);
4087 uint16 result;
4088
4089 /* Check that the byte array is not too long */
4090 if (len > sizeof(result))
4091 ereport(ERROR,
4092 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4093 errmsg("smallint out of range"));
4094
4095 /* Convert it to an integer; most significant bytes come first */
4096 result = 0;
4097 for (int i = 0; i < len; i++)
4098 {
4099 result <<= BITS_PER_BYTE;
4100 result |= ((unsigned char *) VARDATA_ANY(v))[i];
4101 }
4102
4103 PG_RETURN_INT16(result);
4104}
uint16_t uint16
Definition: c.h:501
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_INT16(x)
Definition: fmgr.h:356
#define BITS_PER_BYTE

References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, i, len, PG_GETARG_BYTEA_PP, PG_RETURN_INT16, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_int4()

Datum bytea_int4 ( PG_FUNCTION_ARGS  )

Definition at line 4108 of file varlena.c.

4109{
4110 bytea *v = PG_GETARG_BYTEA_PP(0);
4111 int len = VARSIZE_ANY_EXHDR(v);
4112 uint32 result;
4113
4114 /* Check that the byte array is not too long */
4115 if (len > sizeof(result))
4116 ereport(ERROR,
4117 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4118 errmsg("integer out of range"));
4119
4120 /* Convert it to an integer; most significant bytes come first */
4121 result = 0;
4122 for (int i = 0; i < len; i++)
4123 {
4124 result <<= BITS_PER_BYTE;
4125 result |= ((unsigned char *) VARDATA_ANY(v))[i];
4126 }
4127
4128 PG_RETURN_INT32(result);
4129}
uint32_t uint32
Definition: c.h:502

References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, i, len, PG_GETARG_BYTEA_PP, PG_RETURN_INT32, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_int8()

Datum bytea_int8 ( PG_FUNCTION_ARGS  )

Definition at line 4133 of file varlena.c.

4134{
4135 bytea *v = PG_GETARG_BYTEA_PP(0);
4136 int len = VARSIZE_ANY_EXHDR(v);
4137 uint64 result;
4138
4139 /* Check that the byte array is not too long */
4140 if (len > sizeof(result))
4141 ereport(ERROR,
4142 errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4143 errmsg("bigint out of range"));
4144
4145 /* Convert it to an integer; most significant bytes come first */
4146 result = 0;
4147 for (int i = 0; i < len; i++)
4148 {
4149 result <<= BITS_PER_BYTE;
4150 result |= ((unsigned char *) VARDATA_ANY(v))[i];
4151 }
4152
4153 PG_RETURN_INT64(result);
4154}
uint64_t uint64
Definition: c.h:503

References BITS_PER_BYTE, ereport, errcode(), errmsg(), ERROR, i, len, PG_GETARG_BYTEA_PP, PG_RETURN_INT64, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_larger()

Datum bytea_larger ( PG_FUNCTION_ARGS  )

Definition at line 4028 of file varlena.c.

4029{
4030 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4031 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4032 bytea *result;
4033 int len1,
4034 len2;
4035 int cmp;
4036
4037 len1 = VARSIZE_ANY_EXHDR(arg1);
4038 len2 = VARSIZE_ANY_EXHDR(arg2);
4039
4040 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4041 result = ((cmp > 0) || ((cmp == 0) && (len1 > len2)) ? arg1 : arg2);
4042
4043 PG_RETURN_BYTEA_P(result);
4044}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:743

References cmp(), Min, PG_GETARG_BYTEA_PP, PG_RETURN_BYTEA_P, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_overlay()

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

Definition at line 3165 of file varlena.c.

3166{
3167 bytea *result;
3168 bytea *s1;
3169 bytea *s2;
3170 int sp_pl_sl;
3171
3172 /*
3173 * Check for possible integer-overflow cases. For negative sp, throw a
3174 * "substring length" error because that's what should be expected
3175 * according to the spec's definition of OVERLAY().
3176 */
3177 if (sp <= 0)
3178 ereport(ERROR,
3179 (errcode(ERRCODE_SUBSTRING_ERROR),
3180 errmsg("negative substring length not allowed")));
3181 if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
3182 ereport(ERROR,
3183 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3184 errmsg("integer out of range")));
3185
3186 s1 = bytea_substring(PointerGetDatum(t1), 1, sp - 1, false);
3187 s2 = bytea_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
3188 result = bytea_catenate(s1, t2);
3189 result = bytea_catenate(result, s2);
3190
3191 return result;
3192}
static bool pg_add_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:151
char * s1
char * s2
static bytea * bytea_substring(Datum str, int S, int L, bool length_not_specified)
Definition: varlena.c:3075
static bytea * bytea_catenate(bytea *t1, bytea *t2)
Definition: varlena.c:3000

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

Referenced by byteaoverlay(), and byteaoverlay_no_len().

◆ bytea_reverse()

Datum bytea_reverse ( PG_FUNCTION_ARGS  )

Definition at line 3405 of file varlena.c.

3406{
3407 bytea *v = PG_GETARG_BYTEA_PP(0);
3408 const char *p = VARDATA_ANY(v);
3409 int len = VARSIZE_ANY_EXHDR(v);
3410 const char *endp = p + len;
3411 bytea *result = palloc(len + VARHDRSZ);
3412 char *dst = (char *) VARDATA(result) + len;
3413
3414 SET_VARSIZE(result, len + VARHDRSZ);
3415
3416 while (p < endp)
3417 *(--dst) = *p++;
3418
3419 PG_RETURN_BYTEA_P(result);
3420}

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

◆ bytea_smaller()

Datum bytea_smaller ( PG_FUNCTION_ARGS  )

Definition at line 4047 of file varlena.c.

4048{
4049 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4050 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4051 bytea *result;
4052 int len1,
4053 len2;
4054 int cmp;
4055
4056 len1 = VARSIZE_ANY_EXHDR(arg1);
4057 len2 = VARSIZE_ANY_EXHDR(arg2);
4058
4059 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4060 result = ((cmp < 0) || ((cmp == 0) && (len1 < len2)) ? arg1 : arg2);
4061
4062 PG_RETURN_BYTEA_P(result);
4063}

References cmp(), Min, PG_GETARG_BYTEA_PP, PG_RETURN_BYTEA_P, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ bytea_sortsupport()

Datum bytea_sortsupport ( PG_FUNCTION_ARGS  )

Definition at line 4066 of file varlena.c.

4067{
4069 MemoryContext oldcontext;
4070
4071 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
4072
4073 /* Use generic string SortSupport, forcing "C" collation */
4074 varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
4075
4076 MemoryContextSwitchTo(oldcontext);
4077
4079}

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

◆ bytea_string_agg_finalfn()

Datum bytea_string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 559 of file varlena.c.

560{
562
563 /* cannot be called directly because of internal-type argument */
564 Assert(AggCheckCallContext(fcinfo, NULL));
565
567
568 if (state != NULL)
569 {
570 /* As per comment in transfn, strip data before the cursor position */
571 bytea *result;
572 int strippedlen = state->len - state->cursor;
573
574 result = (bytea *) palloc(strippedlen + VARHDRSZ);
575 SET_VARSIZE(result, strippedlen + VARHDRSZ);
576 memcpy(VARDATA(result), &state->data[state->cursor], strippedlen);
577 PG_RETURN_BYTEA_P(result);
578 }
579 else
581}
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4614
StringInfoData * StringInfo
Definition: stringinfo.h:54
Definition: regguts.h:323

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

◆ bytea_string_agg_transfn()

Datum bytea_string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 506 of file varlena.c.

507{
509
511
512 /* Append the value unless null, preceding it with the delimiter. */
513 if (!PG_ARGISNULL(1))
514 {
516 bool isfirst = false;
517
518 /*
519 * You might think we can just throw away the first delimiter, however
520 * we must keep it as we may be a parallel worker doing partial
521 * aggregation building a state to send to the main process. We need
522 * to keep the delimiter of every aggregation so that the combine
523 * function can properly join up the strings of two separately
524 * partially aggregated results. The first delimiter is only stripped
525 * off in the final function. To know how much to strip off the front
526 * of the string, we store the length of the first delimiter in the
527 * StringInfo's cursor field, which we don't otherwise need here.
528 */
529 if (state == NULL)
530 {
531 state = makeStringAggState(fcinfo);
532 isfirst = true;
533 }
534
535 if (!PG_ARGISNULL(2))
536 {
537 bytea *delim = PG_GETARG_BYTEA_PP(2);
538
540 VARSIZE_ANY_EXHDR(delim));
541 if (isfirst)
542 state->cursor = VARSIZE_ANY_EXHDR(delim);
543 }
544
547 }
548
549 /*
550 * The transition type for string_agg() is declared to be "internal",
551 * which is a pass-by-value type the same size as a pointer.
552 */
553 if (state)
556}
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
static StringInfo makeStringAggState(FunctionCallInfo fcinfo)
Definition: varlena.c:5364

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

◆ bytea_substr()

Datum bytea_substr ( PG_FUNCTION_ARGS  )

Definition at line 3052 of file varlena.c.

3053{
3055 PG_GETARG_INT32(1),
3056 PG_GETARG_INT32(2),
3057 false));
3058}
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269

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

◆ bytea_substr_no_len()

Datum bytea_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3066 of file varlena.c.

3067{
3069 PG_GETARG_INT32(1),
3070 -1,
3071 true));
3072}

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

◆ bytea_substring()

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

Definition at line 3075 of file varlena.c.

3079{
3080 int32 S1; /* adjusted start position */
3081 int32 L1; /* adjusted substring length */
3082 int32 E; /* end position */
3083
3084 /*
3085 * The logic here should generally match text_substring().
3086 */
3087 S1 = Max(S, 1);
3088
3089 if (length_not_specified)
3090 {
3091 /*
3092 * Not passed a length - DatumGetByteaPSlice() grabs everything to the
3093 * end of the string if we pass it a negative value for length.
3094 */
3095 L1 = -1;
3096 }
3097 else if (L < 0)
3098 {
3099 /* SQL99 says to throw an error for E < S, i.e., negative length */
3100 ereport(ERROR,
3101 (errcode(ERRCODE_SUBSTRING_ERROR),
3102 errmsg("negative substring length not allowed")));
3103 L1 = -1; /* silence stupider compilers */
3104 }
3105 else if (pg_add_s32_overflow(S, L, &E))
3106 {
3107 /*
3108 * L could be large enough for S + L to overflow, in which case the
3109 * substring must run to end of string.
3110 */
3111 L1 = -1;
3112 }
3113 else
3114 {
3115 /*
3116 * A zero or negative value for the end position can happen if the
3117 * start was negative or one. SQL99 says to return a zero-length
3118 * string.
3119 */
3120 if (E < 1)
3121 return PG_STR_GET_BYTEA("");
3122
3123 L1 = E - S1;
3124 }
3125
3126 /*
3127 * If the start position is past the end of the string, SQL99 says to
3128 * return a zero-length string -- DatumGetByteaPSlice() will do that for
3129 * us. We need only convert S1 to zero-based starting position.
3130 */
3131 return DatumGetByteaPSlice(str, S1 - 1, L1);
3132}
#define Max(x, y)
Definition: c.h:969
#define DatumGetByteaPSlice(X, m, n)
Definition: fmgr.h:303
#define S(n, x)
Definition: sha1.c:73
#define PG_STR_GET_BYTEA(str_)
Definition: varlena.c:3033

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

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

◆ byteacat()

Datum byteacat ( PG_FUNCTION_ARGS  )

Definition at line 2985 of file varlena.c.

2986{
2987 bytea *t1 = PG_GETARG_BYTEA_PP(0);
2988 bytea *t2 = PG_GETARG_BYTEA_PP(1);
2989
2991}

References bytea_catenate(), PG_GETARG_BYTEA_PP, and PG_RETURN_BYTEA_P.

◆ byteacmp()

Datum byteacmp ( PG_FUNCTION_ARGS  )

Definition at line 4006 of file varlena.c.

4007{
4008 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4009 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4010 int len1,
4011 len2;
4012 int cmp;
4013
4014 len1 = VARSIZE_ANY_EXHDR(arg1);
4015 len2 = VARSIZE_ANY_EXHDR(arg2);
4016
4017 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4018 if ((cmp == 0) && (len1 != len2))
4019 cmp = (len1 < len2) ? -1 : 1;
4020
4021 PG_FREE_IF_COPY(arg1, 0);
4022 PG_FREE_IF_COPY(arg2, 1);
4023
4025}

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

Referenced by gbt_bitcmp(), and gbt_byteacmp().

◆ byteaeq()

Datum byteaeq ( PG_FUNCTION_ARGS  )

Definition at line 3862 of file varlena.c.

3863{
3864 Datum arg1 = PG_GETARG_DATUM(0);
3865 Datum arg2 = PG_GETARG_DATUM(1);
3866 bool result;
3867 Size len1,
3868 len2;
3869
3870 /*
3871 * We can use a fast path for unequal lengths, which might save us from
3872 * having to detoast one or both values.
3873 */
3874 len1 = toast_raw_datum_size(arg1);
3875 len2 = toast_raw_datum_size(arg2);
3876 if (len1 != len2)
3877 result = false;
3878 else
3879 {
3880 bytea *barg1 = DatumGetByteaPP(arg1);
3881 bytea *barg2 = DatumGetByteaPP(arg2);
3882
3883 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3884 len1 - VARHDRSZ) == 0);
3885
3886 PG_FREE_IF_COPY(barg1, 0);
3887 PG_FREE_IF_COPY(barg2, 1);
3888 }
3889
3890 PG_RETURN_BOOL(result);
3891}
size_t Size
Definition: c.h:576
Size toast_raw_datum_size(Datum value)
Definition: detoast.c:545
#define DatumGetByteaPP(X)
Definition: fmgr.h:291

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

Referenced by gbt_byteaeq().

◆ byteage()

Datum byteage ( PG_FUNCTION_ARGS  )

Definition at line 3986 of file varlena.c.

3987{
3988 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3989 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3990 int len1,
3991 len2;
3992 int cmp;
3993
3994 len1 = VARSIZE_ANY_EXHDR(arg1);
3995 len2 = VARSIZE_ANY_EXHDR(arg2);
3996
3997 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3998
3999 PG_FREE_IF_COPY(arg1, 0);
4000 PG_FREE_IF_COPY(arg2, 1);
4001
4002 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));
4003}

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

Referenced by gbt_byteage().

◆ byteaGetBit()

Datum byteaGetBit ( PG_FUNCTION_ARGS  )

Definition at line 3285 of file varlena.c.

3286{
3287 bytea *v = PG_GETARG_BYTEA_PP(0);
3288 int64 n = PG_GETARG_INT64(1);
3289 int byteNo,
3290 bitNo;
3291 int len;
3292 int byte;
3293
3295
3296 if (n < 0 || n >= (int64) len * 8)
3297 ereport(ERROR,
3298 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3299 errmsg("index %lld out of valid range, 0..%lld",
3300 (long long) n, (long long) len * 8 - 1)));
3301
3302 /* n/8 is now known < len, so safe to cast to int */
3303 byteNo = (int) (n / 8);
3304 bitNo = (int) (n % 8);
3305
3306 byte = ((unsigned char *) VARDATA_ANY(v))[byteNo];
3307
3308 if (byte & (1 << bitNo))
3309 PG_RETURN_INT32(1);
3310 else
3311 PG_RETURN_INT32(0);
3312}
int64_t int64
Definition: c.h:499
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

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

◆ byteaGetByte()

Datum byteaGetByte ( PG_FUNCTION_ARGS  )

Definition at line 3256 of file varlena.c.

3257{
3258 bytea *v = PG_GETARG_BYTEA_PP(0);
3259 int32 n = PG_GETARG_INT32(1);
3260 int len;
3261 int byte;
3262
3264
3265 if (n < 0 || n >= len)
3266 ereport(ERROR,
3267 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3268 errmsg("index %d out of valid range, 0..%d",
3269 n, len - 1)));
3270
3271 byte = ((unsigned char *) VARDATA_ANY(v))[n];
3272
3273 PG_RETURN_INT32(byte);
3274}

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

◆ byteagt()

Datum byteagt ( PG_FUNCTION_ARGS  )

Definition at line 3966 of file varlena.c.

3967{
3968 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3969 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3970 int len1,
3971 len2;
3972 int cmp;
3973
3974 len1 = VARSIZE_ANY_EXHDR(arg1);
3975 len2 = VARSIZE_ANY_EXHDR(arg2);
3976
3977 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3978
3979 PG_FREE_IF_COPY(arg1, 0);
3980 PG_FREE_IF_COPY(arg2, 1);
3981
3982 PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));
3983}

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

Referenced by gbt_byteagt().

◆ byteain()

Datum byteain ( PG_FUNCTION_ARGS  )

Definition at line 298 of file varlena.c.

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

References ereturn, errcode(), errmsg(), hex_decode_safe(), len, palloc(), PG_GETARG_CSTRING, PG_RETURN_BYTEA_P, SET_VARSIZE, VAL, VARDATA, and VARHDRSZ.

Referenced by CreateTriggerFiringOn(), and string_to_datum().

◆ byteale()

Datum byteale ( PG_FUNCTION_ARGS  )

Definition at line 3946 of file varlena.c.

3947{
3948 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3949 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3950 int len1,
3951 len2;
3952 int cmp;
3953
3954 len1 = VARSIZE_ANY_EXHDR(arg1);
3955 len2 = VARSIZE_ANY_EXHDR(arg2);
3956
3957 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3958
3959 PG_FREE_IF_COPY(arg1, 0);
3960 PG_FREE_IF_COPY(arg2, 1);
3961
3962 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));
3963}

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

Referenced by gbt_byteale().

◆ bytealt()

Datum bytealt ( PG_FUNCTION_ARGS  )

Definition at line 3926 of file varlena.c.

3927{
3928 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3929 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3930 int len1,
3931 len2;
3932 int cmp;
3933
3934 len1 = VARSIZE_ANY_EXHDR(arg1);
3935 len2 = VARSIZE_ANY_EXHDR(arg2);
3936
3937 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3938
3939 PG_FREE_IF_COPY(arg1, 0);
3940 PG_FREE_IF_COPY(arg2, 1);
3941
3942 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
3943}

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

Referenced by gbt_bytealt().

◆ byteane()

Datum byteane ( PG_FUNCTION_ARGS  )

Definition at line 3894 of file varlena.c.

3895{
3896 Datum arg1 = PG_GETARG_DATUM(0);
3897 Datum arg2 = PG_GETARG_DATUM(1);
3898 bool result;
3899 Size len1,
3900 len2;
3901
3902 /*
3903 * We can use a fast path for unequal lengths, which might save us from
3904 * having to detoast one or both values.
3905 */
3906 len1 = toast_raw_datum_size(arg1);
3907 len2 = toast_raw_datum_size(arg2);
3908 if (len1 != len2)
3909 result = true;
3910 else
3911 {
3912 bytea *barg1 = DatumGetByteaPP(arg1);
3913 bytea *barg2 = DatumGetByteaPP(arg2);
3914
3915 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3916 len1 - VARHDRSZ) != 0);
3917
3918 PG_FREE_IF_COPY(barg1, 0);
3919 PG_FREE_IF_COPY(barg2, 1);
3920 }
3921
3922 PG_RETURN_BOOL(result);
3923}

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

◆ byteaoctetlen()

Datum byteaoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 2969 of file varlena.c.

2970{
2972
2973 /* We need not detoast the input at all */
2975}

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

◆ byteaout()

Datum byteaout ( PG_FUNCTION_ARGS  )

Definition at line 396 of file varlena.c.

397{
398 bytea *vlena = PG_GETARG_BYTEA_PP(0);
399 char *result;
400 char *rp;
401
403 {
404 /* Print hex format */
405 rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1);
406 *rp++ = '\\';
407 *rp++ = 'x';
408 rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp);
409 }
411 {
412 /* Print traditional escaped format */
413 char *vp;
414 uint64 len;
415 int i;
416
417 len = 1; /* empty string has 1 char */
418 vp = VARDATA_ANY(vlena);
419 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
420 {
421 if (*vp == '\\')
422 len += 2;
423 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
424 len += 4;
425 else
426 len++;
427 }
428
429 /*
430 * In principle len can't overflow uint32 if the input fit in 1GB, but
431 * for safety let's check rather than relying on palloc's internal
432 * check.
433 */
434 if (len > MaxAllocSize)
436 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
437 errmsg_internal("result of bytea output conversion is too large")));
438 rp = result = (char *) palloc(len);
439
440 vp = VARDATA_ANY(vlena);
441 for (i = VARSIZE_ANY_EXHDR(vlena); i != 0; i--, vp++)
442 {
443 if (*vp == '\\')
444 {
445 *rp++ = '\\';
446 *rp++ = '\\';
447 }
448 else if ((unsigned char) *vp < 0x20 || (unsigned char) *vp > 0x7e)
449 {
450 int val; /* holds unprintable chars */
451
452 val = *vp;
453 rp[0] = '\\';
454 rp[3] = DIG(val & 07);
455 val >>= 3;
456 rp[2] = DIG(val & 07);
457 val >>= 3;
458 rp[1] = DIG(val & 03);
459 rp += 4;
460 }
461 else
462 *rp++ = *vp;
463 }
464 }
465 else
466 {
467 elog(ERROR, "unrecognized \"bytea_output\" setting: %d",
469 rp = result = NULL; /* keep compiler quiet */
470 }
471 *rp = '\0';
472 PG_RETURN_CSTRING(result);
473}
@ BYTEA_OUTPUT_HEX
Definition: bytea.h:22
@ BYTEA_OUTPUT_ESCAPE
Definition: bytea.h:21
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
uint64 hex_encode(const char *src, size_t len, char *dst)
Definition: encode.c:181
#define MaxAllocSize
Definition: fe_memutils.h:22
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
long val
Definition: informix.c:689
int bytea_output
Definition: varlena.c:48
#define DIG(VAL)
Definition: varlena.c:284

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

Referenced by pg_mcv_list_out().

◆ byteaoverlay()

Datum byteaoverlay ( PG_FUNCTION_ARGS  )

Definition at line 3142 of file varlena.c.

3143{
3144 bytea *t1 = PG_GETARG_BYTEA_PP(0);
3145 bytea *t2 = PG_GETARG_BYTEA_PP(1);
3146 int sp = PG_GETARG_INT32(2); /* substring start position */
3147 int sl = PG_GETARG_INT32(3); /* substring length */
3148
3149 PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3150}
static bytea * bytea_overlay(bytea *t1, bytea *t2, int sp, int sl)
Definition: varlena.c:3165

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

◆ byteaoverlay_no_len()

Datum byteaoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 3153 of file varlena.c.

3154{
3155 bytea *t1 = PG_GETARG_BYTEA_PP(0);
3156 bytea *t2 = PG_GETARG_BYTEA_PP(1);
3157 int sp = PG_GETARG_INT32(2); /* substring start position */
3158 int sl;
3159
3160 sl = VARSIZE_ANY_EXHDR(t2); /* defaults to length(t2) */
3161 PG_RETURN_BYTEA_P(bytea_overlay(t1, t2, sp, sl));
3162}

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

◆ byteapos()

Datum byteapos ( PG_FUNCTION_ARGS  )

Definition at line 3212 of file varlena.c.

3213{
3214 bytea *t1 = PG_GETARG_BYTEA_PP(0);
3215 bytea *t2 = PG_GETARG_BYTEA_PP(1);
3216 int pos;
3217 int px,
3218 p;
3219 int len1,
3220 len2;
3221 char *p1,
3222 *p2;
3223
3224 len1 = VARSIZE_ANY_EXHDR(t1);
3225 len2 = VARSIZE_ANY_EXHDR(t2);
3226
3227 if (len2 <= 0)
3228 PG_RETURN_INT32(1); /* result for empty pattern */
3229
3230 p1 = VARDATA_ANY(t1);
3231 p2 = VARDATA_ANY(t2);
3232
3233 pos = 0;
3234 px = (len1 - len2);
3235 for (p = 0; p <= px; p++)
3236 {
3237 if ((*p2 == *p1) && (memcmp(p1, p2, len2) == 0))
3238 {
3239 pos = p + 1;
3240 break;
3241 };
3242 p1++;
3243 };
3244
3245 PG_RETURN_INT32(pos);
3246}
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)

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

◆ bytearecv()

Datum bytearecv ( PG_FUNCTION_ARGS  )

Definition at line 479 of file varlena.c.

480{
482 bytea *result;
483 int nbytes;
484
485 nbytes = buf->len - buf->cursor;
486 result = (bytea *) palloc(nbytes + VARHDRSZ);
487 SET_VARSIZE(result, nbytes + VARHDRSZ);
488 pq_copymsgbytes(buf, VARDATA(result), nbytes);
489 PG_RETURN_BYTEA_P(result);
490}
void pq_copymsgbytes(StringInfo msg, void *buf, int datalen)
Definition: pqformat.c:528

References buf, palloc(), PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_copymsgbytes(), SET_VARSIZE, VARDATA, and VARHDRSZ.

◆ byteasend()

Datum byteasend ( PG_FUNCTION_ARGS  )

Definition at line 498 of file varlena.c.

499{
500 bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
501
502 PG_RETURN_BYTEA_P(vlena);
503}
#define PG_GETARG_BYTEA_P_COPY(n)
Definition: fmgr.h:314

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

◆ byteaSetBit()

Datum byteaSetBit ( PG_FUNCTION_ARGS  )

Definition at line 3355 of file varlena.c.

3356{
3357 bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3358 int64 n = PG_GETARG_INT64(1);
3359 int32 newBit = PG_GETARG_INT32(2);
3360 int len;
3361 int oldByte,
3362 newByte;
3363 int byteNo,
3364 bitNo;
3365
3366 len = VARSIZE(res) - VARHDRSZ;
3367
3368 if (n < 0 || n >= (int64) len * 8)
3369 ereport(ERROR,
3370 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3371 errmsg("index %lld out of valid range, 0..%lld",
3372 (long long) n, (long long) len * 8 - 1)));
3373
3374 /* n/8 is now known < len, so safe to cast to int */
3375 byteNo = (int) (n / 8);
3376 bitNo = (int) (n % 8);
3377
3378 /*
3379 * sanity check!
3380 */
3381 if (newBit != 0 && newBit != 1)
3382 ereport(ERROR,
3383 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
3384 errmsg("new bit must be 0 or 1")));
3385
3386 /*
3387 * Update the byte.
3388 */
3389 oldByte = ((unsigned char *) VARDATA(res))[byteNo];
3390
3391 if (newBit == 0)
3392 newByte = oldByte & (~(1 << bitNo));
3393 else
3394 newByte = oldByte | (1 << bitNo);
3395
3396 ((unsigned char *) VARDATA(res))[byteNo] = newByte;
3397
3398 PG_RETURN_BYTEA_P(res);
3399}
#define VARSIZE(PTR)
Definition: varatt.h:279

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

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

Definition at line 3323 of file varlena.c.

3324{
3325 bytea *res = PG_GETARG_BYTEA_P_COPY(0);
3326 int32 n = PG_GETARG_INT32(1);
3327 int32 newByte = PG_GETARG_INT32(2);
3328 int len;
3329
3330 len = VARSIZE(res) - VARHDRSZ;
3331
3332 if (n < 0 || n >= len)
3333 ereport(ERROR,
3334 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
3335 errmsg("index %d out of valid range, 0..%d",
3336 n, len - 1)));
3337
3338 /*
3339 * Now set the byte.
3340 */
3341 ((unsigned char *) VARDATA(res))[n] = newByte;
3342
3343 PG_RETURN_BYTEA_P(res);
3344}

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

◆ charlen_to_bytelen()

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

Definition at line 814 of file varlena.c.

815{
817 {
818 /* Optimization for single-byte encodings */
819 return n;
820 }
821 else
822 {
823 const char *s;
824
825 for (s = p; n > 0; n--)
826 s += pg_mblen(s);
827
828 return s - p;
829 }
830}
int pg_database_encoding_max_length(void)
Definition: mbutils.c:1546
int pg_mblen(const char *mbstr)
Definition: mbutils.c:1023

References pg_database_encoding_max_length(), and pg_mblen().

Referenced by appendStringInfoRegexpSubstr(), and replace_text_regexp().

◆ check_collation_set()

static void check_collation_set ( Oid  collid)
static

Definition at line 1581 of file varlena.c.

1582{
1583 if (!OidIsValid(collid))
1584 {
1585 /*
1586 * This typically means that the parser could not resolve a conflict
1587 * of implicit collations, so report it that way.
1588 */
1589 ereport(ERROR,
1590 (errcode(ERRCODE_INDETERMINATE_COLLATION),
1591 errmsg("could not determine which collation to use for string comparison"),
1592 errhint("Use the COLLATE clause to set the collation explicitly.")));
1593 }
1594}

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

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

◆ check_replace_text_has_escape()

static int check_replace_text_has_escape ( const text replace_text)
static

Definition at line 4275 of file varlena.c.

4276{
4277 int result = 0;
4278 const char *p = VARDATA_ANY(replace_text);
4279 const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4280
4281 while (p < p_end)
4282 {
4283 /* Find next escape char, if any. */
4284 p = memchr(p, '\\', p_end - p);
4285 if (p == NULL)
4286 break;
4287 p++;
4288 /* Note: a backslash at the end doesn't require extra processing. */
4289 if (p < p_end)
4290 {
4291 if (*p >= '1' && *p <= '9')
4292 return 2; /* Found a submatch specifier, so done */
4293 result = 1; /* Found some other sequence, keep looking */
4294 p++;
4295 }
4296 }
4297 return result;
4298}

References replace_text(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by replace_text_regexp().

◆ concat_internal()

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

Definition at line 5624 of file varlena.c.

5626{
5627 text *result;
5629 FmgrInfo *foutcache;
5630 bool first_arg = true;
5631 int i;
5632
5633 /*
5634 * concat(VARIADIC some-array) is essentially equivalent to
5635 * array_to_text(), ie concat the array elements with the given separator.
5636 * So we just pass the case off to that code.
5637 */
5638 if (get_fn_expr_variadic(fcinfo->flinfo))
5639 {
5640 ArrayType *arr;
5641
5642 /* Should have just the one argument */
5643 Assert(argidx == PG_NARGS() - 1);
5644
5645 /* concat(VARIADIC NULL) is defined as NULL */
5646 if (PG_ARGISNULL(argidx))
5647 return NULL;
5648
5649 /*
5650 * Non-null argument had better be an array. We assume that any call
5651 * context that could let get_fn_expr_variadic return true will have
5652 * checked that a VARIADIC-labeled parameter actually is an array. So
5653 * it should be okay to just Assert that it's an array rather than
5654 * doing a full-fledged error check.
5655 */
5657
5658 /* OK, safe to fetch the array value */
5659 arr = PG_GETARG_ARRAYTYPE_P(argidx);
5660
5661 /*
5662 * And serialize the array. We tell array_to_text to ignore null
5663 * elements, which matches the behavior of the loop below.
5664 */
5665 return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5666 }
5667
5668 /* Normal case without explicit VARIADIC marker */
5670
5671 /* Get output function info, building it if first time through */
5672 foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5673 if (foutcache == NULL)
5674 foutcache = build_concat_foutcache(fcinfo, argidx);
5675
5676 for (i = argidx; i < PG_NARGS(); i++)
5677 {
5678 if (!PG_ARGISNULL(i))
5679 {
5681
5682 /* add separator if appropriate */
5683 if (first_arg)
5684 first_arg = false;
5685 else
5686 appendStringInfoString(&str, sepstr);
5687
5688 /* call the appropriate type output function, append the result */
5690 OutputFunctionCall(&foutcache[i], value));
5691 }
5692 }
5693
5694 result = cstring_to_text_with_len(str.data, str.len);
5695 pfree(str.data);
5696
5697 return result;
5698}
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2044
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2915
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5586

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

Referenced by text_concat(), and text_concat_ws().

◆ convert_to_base()

static text * convert_to_base ( uint64  value,
int  base 
)
inlinestatic

Definition at line 5132 of file varlena.c.

5133{
5134 const char *digits = "0123456789abcdef";
5135
5136 /* We size the buffer for to_bin's longest possible return value. */
5137 char buf[sizeof(uint64) * BITS_PER_BYTE];
5138 char *const end = buf + sizeof(buf);
5139 char *ptr = end;
5140
5141 Assert(base > 1);
5142 Assert(base <= 16);
5143
5144 do
5145 {
5146 *--ptr = digits[value % base];
5147 value /= base;
5148 } while (ptr > buf && value);
5149
5150 return cstring_to_text_with_len(ptr, end - ptr);
5151}
int digits
Definition: informix.c:691

References Assert(), BITS_PER_BYTE, buf, cstring_to_text_with_len(), digits, and value.

Referenced by to_bin32(), to_bin64(), to_hex32(), to_hex64(), to_oct32(), and to_oct64().

◆ cstring_to_text()

text * cstring_to_text ( const char *  s)

Definition at line 192 of file varlena.c.

193{
194 return cstring_to_text_with_len(s, strlen(s));
195}

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(), casefold(), 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(), icu_unicode_version(), 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(), ParameterAclCreate(), ParameterAclLookup(), pg_collation_actual_version(), pg_collation_for(), pg_column_compression(), pg_crypt(), pg_current_logfile(), pg_database_collation_actual_version(), pg_describe_object(), pg_export_snapshot(), pg_get_statisticsobjdef_expressions(), pg_get_wal_replay_pause_state(), pg_parameter_aclmask(), 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(), split_part(), ssl_cipher(), ssl_client_dn(), ssl_issuer_dn(), ssl_version(), string_to_text(), test_canonicalize_path(), test_slru_page_read(), test_slru_page_readonly(), text_substring(), textin(), timeofday(), timetz_at_local(), tsquerytree(), unaccent_dict(), unicode_version(), upper(), xml_encode_special_chars(), xml_in(), and xml_recv().

◆ cstring_to_text_with_len()

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

Definition at line 204 of file varlena.c.

205{
206 text *result = (text *) palloc(len + VARHDRSZ);
207
208 SET_VARSIZE(result, len + VARHDRSZ);
209 memcpy(VARDATA(result), s, len);
210
211 return result;
212}

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

Referenced by array_to_json(), array_to_json_pretty(), array_to_text_internal(), brin_minmax_multi_summary_out(), build_regexp_match_result(), build_regexp_split_result(), build_test_match_result(), cash_words(), compute_tsvector_stats(), concat_internal(), convert_to_base(), cstring_to_text(), daitch_mokotoff_coding(), datum_to_json(), do_text_output_multiline(), dotrim(), each_object_field_end(), each_worker_jsonb(), elements_array_element_end(), ExecEvalMergeSupportFunc(), ExecEvalXmlExpr(), executeDateTimeMethod(), executeLikeRegex(), find_or_create_child_node(), 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_noargs(), json_build_array_worker(), json_build_object_noargs(), json_build_object_worker(), 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(), pg_get_function_sqlbody(), 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(), transform_json_string_values(), tsquerytree(), tsvector_to_array(), tsvector_unnest(), unistr(), varchar(), varchar_input(), xmltext(), xmltotext_with_options(), and xslt_process().

◆ getClosestMatch()

const char * getClosestMatch ( ClosestMatchState state)

Definition at line 6445 of file varlena.c.

6446{
6447 Assert(state);
6448
6449 return state->match;
6450}

References Assert().

Referenced by dblink_fdw_validator(), file_fdw_validator(), postgres_fdw_validator(), and postgresql_fdw_validator().

◆ hexval()

static unsigned int hexval ( unsigned char  c)
static

Definition at line 6674 of file varlena.c.

6675{
6676 if (c >= '0' && c <= '9')
6677 return c - '0';
6678 if (c >= 'a' && c <= 'f')
6679 return c - 'a' + 0xA;
6680 if (c >= 'A' && c <= 'F')
6681 return c - 'A' + 0xA;
6682 elog(ERROR, "invalid hexadecimal digit");
6683 return 0; /* not reached */
6684}
char * c

References elog, and ERROR.

Referenced by hexval_n().

◆ hexval_n()

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

Definition at line 6690 of file varlena.c.

6691{
6692 unsigned int result = 0;
6693
6694 for (size_t i = 0; i < n; i++)
6695 result += hexval(instr[i]) << (4 * (n - i - 1));
6696
6697 return result;
6698}
static unsigned int hexval(unsigned char c)
Definition: varlena.c:6674

References hexval(), and i.

Referenced by unistr().

◆ icu_unicode_version()

Datum icu_unicode_version ( PG_FUNCTION_ARGS  )

Definition at line 6504 of file varlena.c.

6505{
6506#ifdef USE_ICU
6507 PG_RETURN_TEXT_P(cstring_to_text(U_UNICODE_VERSION));
6508#else
6510#endif
6511}
text * cstring_to_text(const char *s)
Definition: varlena.c:192

References cstring_to_text(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

Referenced by main().

◆ initClosestMatch()

void initClosestMatch ( ClosestMatchState state,
const char *  source,
int  max_d 
)

Definition at line 6390 of file varlena.c.

6391{
6392 Assert(state);
6393 Assert(max_d >= 0);
6394
6395 state->source = source;
6396 state->min_d = -1;
6397 state->max_d = max_d;
6398 state->match = NULL;
6399}
static rewind_source * source
Definition: pg_rewind.c:89

References Assert(), and source.

Referenced by dblink_fdw_validator(), file_fdw_validator(), postgres_fdw_validator(), and postgresql_fdw_validator().

◆ int2_bytea()

Datum int2_bytea ( PG_FUNCTION_ARGS  )

Definition at line 4158 of file varlena.c.

4159{
4160 return int2send(fcinfo);
4161}
Datum int2send(PG_FUNCTION_ARGS)
Definition: int.c:98

References int2send().

◆ int4_bytea()

Datum int4_bytea ( PG_FUNCTION_ARGS  )

Definition at line 4165 of file varlena.c.

4166{
4167 return int4send(fcinfo);
4168}
Datum int4send(PG_FUNCTION_ARGS)
Definition: int.c:322

References int4send().

◆ int8_bytea()

Datum int8_bytea ( PG_FUNCTION_ARGS  )

Definition at line 4172 of file varlena.c.

4173{
4174 return int8send(fcinfo);
4175}
Datum int8send(PG_FUNCTION_ARGS)
Definition: int8.c:94

References int8send().

◆ internal_text_pattern_compare()

static int internal_text_pattern_compare ( text arg1,
text arg2 
)
static

Definition at line 2844 of file varlena.c.

2845{
2846 int result;
2847 int len1,
2848 len2;
2849
2850 len1 = VARSIZE_ANY_EXHDR(arg1);
2851 len2 = VARSIZE_ANY_EXHDR(arg2);
2852
2853 result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
2854 if (result != 0)
2855 return result;
2856 else if (len1 < len2)
2857 return -1;
2858 else if (len1 > len2)
2859 return 1;
2860 else
2861 return 0;
2862}

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

◆ isxdigits_n()

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

Definition at line 6664 of file varlena.c.

6665{
6666 for (size_t i = 0; i < n; i++)
6667 if (!isxdigit((unsigned char) instr[i]))
6668 return false;
6669
6670 return true;
6671}

References i.

Referenced by unistr().

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5364 of file varlena.c.

5365{
5367 MemoryContext aggcontext;
5368 MemoryContext oldcontext;
5369
5370 if (!AggCheckCallContext(fcinfo, &aggcontext))
5371 {
5372 /* cannot be called directly because of internal-type argument */
5373 elog(ERROR, "string_agg_transfn called in non-aggregate context");
5374 }
5375
5376 /*
5377 * Create state in aggregate context. It'll stay there across subsequent
5378 * calls.
5379 */
5380 oldcontext = MemoryContextSwitchTo(aggcontext);
5382 MemoryContextSwitchTo(oldcontext);
5383
5384 return state;
5385}
StringInfo makeStringInfo(void)
Definition: stringinfo.c:72

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

Referenced by bytea_string_agg_transfn(), string_agg_combine(), string_agg_deserialize(), and string_agg_transfn().

◆ name_text()

Datum name_text ( PG_FUNCTION_ARGS  )

Definition at line 3450 of file varlena.c.

3451{
3452 Name s = PG_GETARG_NAME(0);
3453
3455}

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

Referenced by nameiclike(), and nameicnlike().

◆ nameeqtext()

Datum nameeqtext ( PG_FUNCTION_ARGS  )

Definition at line 2647 of file varlena.c.

2648{
2649 Name arg1 = PG_GETARG_NAME(0);
2650 text *arg2 = PG_GETARG_TEXT_PP(1);
2651 size_t len1 = strlen(NameStr(*arg1));
2652 size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2654 bool result;
2655
2657
2658 if (collid == C_COLLATION_OID)
2659 result = (len1 == len2 &&
2660 memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2661 else
2662 result = (varstr_cmp(NameStr(*arg1), len1,
2663 VARDATA_ANY(arg2), len2,
2664 collid) == 0);
2665
2666 PG_FREE_IF_COPY(arg2, 1);
2667
2668 PG_RETURN_BOOL(result);
2669}

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

◆ namefastcmp_c()

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

Definition at line 2135 of file varlena.c.

2136{
2137 Name arg1 = DatumGetName(x);
2138 Name arg2 = DatumGetName(y);
2139
2140 return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN);
2141}
#define NAMEDATALEN
static Name DatumGetName(Datum X)
Definition: postgres.h:365

References DatumGetName(), NAMEDATALEN, NameStr, x, and y.

Referenced by varstr_sortsupport().

◆ namefastcmp_locale()

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

Definition at line 2178 of file varlena.c.

2179{
2180 Name arg1 = DatumGetName(x);
2181 Name arg2 = DatumGetName(y);
2182
2183 return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)),
2184 NameStr(*arg2), strlen(NameStr(*arg2)),
2185 ssup);
2186}
static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup)
Definition: varlena.c:2192

References DatumGetName(), NameStr, varstrfastcmp_locale(), x, and y.

Referenced by varstr_sortsupport().

◆ namegetext()

Datum namegetext ( PG_FUNCTION_ARGS  )

Definition at line 2803 of file varlena.c.

2804{
2806}
#define CmpCall(cmpfunc)
Definition: varlena.c:2778
Datum btnametextcmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2747

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ namegttext()

Datum namegttext ( PG_FUNCTION_ARGS  )

Definition at line 2797 of file varlena.c.

2798{
2800}

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ nameletext()

Datum nameletext ( PG_FUNCTION_ARGS  )

Definition at line 2791 of file varlena.c.

2792{
2794}

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ namelttext()

Datum namelttext ( PG_FUNCTION_ARGS  )

Definition at line 2785 of file varlena.c.

2786{
2788}

References btnametextcmp(), CmpCall, and PG_RETURN_BOOL.

◆ namenetext()

Datum namenetext ( PG_FUNCTION_ARGS  )

Definition at line 2697 of file varlena.c.

2698{
2699 Name arg1 = PG_GETARG_NAME(0);
2700 text *arg2 = PG_GETARG_TEXT_PP(1);
2701 size_t len1 = strlen(NameStr(*arg1));
2702 size_t len2 = VARSIZE_ANY_EXHDR(arg2);
2704 bool result;
2705
2707
2708 if (collid == C_COLLATION_OID)
2709 result = !(len1 == len2 &&
2710 memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0);
2711 else
2712 result = !(varstr_cmp(NameStr(*arg1), len1,
2713 VARDATA_ANY(arg2), len2,
2714 collid) == 0);
2715
2716 PG_FREE_IF_COPY(arg2, 1);
2717
2718 PG_RETURN_BOOL(result);
2719}

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

◆ pg_column_compression()

Datum pg_column_compression ( PG_FUNCTION_ARGS  )

Definition at line 5263 of file varlena.c.

5264{
5265 int typlen;
5266 char *result;
5267 ToastCompressionId cmid;
5268
5269 /* On first call, get the input type's typlen, and save at *fn_extra */
5270 if (fcinfo->flinfo->fn_extra == NULL)
5271 {
5272 /* Lookup the datatype of the supplied argument */
5273 Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5274
5275 typlen = get_typlen(argtypeid);
5276 if (typlen == 0) /* should not happen */
5277 elog(ERROR, "cache lookup failed for type %u", argtypeid);
5278
5279 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5280 sizeof(int));
5281 *((int *) fcinfo->flinfo->fn_extra) = typlen;
5282 }
5283 else
5284 typlen = *((int *) fcinfo->flinfo->fn_extra);
5285
5286 if (typlen != -1)
5288
5289 /* get the compression method id stored in the compressed varlena */
5290 cmid = toast_get_compression_id((struct varlena *)
5292 if (cmid == TOAST_INVALID_COMPRESSION_ID)
5294
5295 /* convert compression method id to compression method name */
5296 switch (cmid)
5297 {
5299 result = "pglz";
5300 break;
5302 result = "lz4";
5303 break;
5304 default:
5305 elog(ERROR, "invalid compression method id %d", cmid);
5306 }
5307
5309}
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2280
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
ToastCompressionId toast_get_compression_id(struct varlena *attr)
ToastCompressionId
@ TOAST_INVALID_COMPRESSION_ID
@ TOAST_LZ4_COMPRESSION_ID
@ TOAST_PGLZ_COMPRESSION_ID

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.

◆ pg_column_size()

Datum pg_column_size ( PG_FUNCTION_ARGS  )

Definition at line 5216 of file varlena.c.

5217{
5219 int32 result;
5220 int typlen;
5221
5222 /* On first call, get the input type's typlen, and save at *fn_extra */
5223 if (fcinfo->flinfo->fn_extra == NULL)
5224 {
5225 /* Lookup the datatype of the supplied argument */
5226 Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5227
5228 typlen = get_typlen(argtypeid);
5229 if (typlen == 0) /* should not happen */
5230 elog(ERROR, "cache lookup failed for type %u", argtypeid);
5231
5232 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5233 sizeof(int));
5234 *((int *) fcinfo->flinfo->fn_extra) = typlen;
5235 }
5236 else
5237 typlen = *((int *) fcinfo->flinfo->fn_extra);
5238
5239 if (typlen == -1)
5240 {
5241 /* varlena type, possibly toasted */
5242 result = toast_datum_size(value);
5243 }
5244 else if (typlen == -2)
5245 {
5246 /* cstring */
5247 result = strlen(DatumGetCString(value)) + 1;
5248 }
5249 else
5250 {
5251 /* ordinary fixed-width type */
5252 result = typlen;
5253 }
5254
5255 PG_RETURN_INT32(result);
5256}
Size toast_datum_size(Datum value)
Definition: detoast.c:601
static char * DatumGetCString(Datum X)
Definition: postgres.h:340

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

◆ pg_column_toast_chunk_id()

Datum pg_column_toast_chunk_id ( PG_FUNCTION_ARGS  )

Definition at line 5316 of file varlena.c.

5317{
5318 int typlen;
5319 struct varlena *attr;
5320 struct varatt_external toast_pointer;
5321
5322 /* On first call, get the input type's typlen, and save at *fn_extra */
5323 if (fcinfo->flinfo->fn_extra == NULL)
5324 {
5325 /* Lookup the datatype of the supplied argument */
5326 Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5327
5328 typlen = get_typlen(argtypeid);
5329 if (typlen == 0) /* should not happen */
5330 elog(ERROR, "cache lookup failed for type %u", argtypeid);
5331
5332 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5333 sizeof(int));
5334 *((int *) fcinfo->flinfo->fn_extra) = typlen;
5335 }
5336 else
5337 typlen = *((int *) fcinfo->flinfo->fn_extra);
5338
5339 if (typlen != -1)
5341
5342 attr = (struct varlena *) DatumGetPointer(PG_GETARG_DATUM(0));
5343
5344 if (!VARATT_IS_EXTERNAL_ONDISK(attr))
5346
5347 VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
5348
5349 PG_RETURN_OID(toast_pointer.va_valueid);
5350}
#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr)
Definition: detoast.h:22
#define PG_RETURN_OID(x)
Definition: fmgr.h:360
#define VARATT_IS_EXTERNAL_ONDISK(PTR)
Definition: varatt.h:290

References DatumGetPointer(), elog, ERROR, get_fn_expr_argtype(), get_typlen(), MemoryContextAlloc(), PG_GETARG_DATUM, PG_RETURN_NULL, PG_RETURN_OID, varatt_external::va_valueid, VARATT_EXTERNAL_GET_POINTER, and VARATT_IS_EXTERNAL_ONDISK.

◆ replace_text()

Datum replace_text ( PG_FUNCTION_ARGS  )

Definition at line 4198 of file varlena.c.

4199{
4200 text *src_text = PG_GETARG_TEXT_PP(0);
4201 text *from_sub_text = PG_GETARG_TEXT_PP(1);
4202 text *to_sub_text = PG_GETARG_TEXT_PP(2);
4203 int src_text_len;
4204 int from_sub_text_len;
4206 text *ret_text;
4207 int chunk_len;
4208 char *curr_ptr;
4209 char *start_ptr;
4211 bool found;
4212
4213 src_text_len = VARSIZE_ANY_EXHDR(src_text);
4214 from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4215
4216 /* Return unmodified source string if empty source or pattern */
4217 if (src_text_len < 1 || from_sub_text_len < 1)
4218 {
4219 PG_RETURN_TEXT_P(src_text);
4220 }
4221
4222 text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4223
4224 found = text_position_next(&state);
4225
4226 /* When the from_sub_text is not found, there is nothing to do. */
4227 if (!found)
4228 {
4230 PG_RETURN_TEXT_P(src_text);
4231 }
4233 start_ptr = VARDATA_ANY(src_text);
4234
4236
4237 do
4238 {
4240
4241 /* copy the data skipped over by last text_position_next() */
4242 chunk_len = curr_ptr - start_ptr;
4243 appendBinaryStringInfo(&str, start_ptr, chunk_len);
4244
4245 appendStringInfoText(&str, to_sub_text);
4246
4247 start_ptr = curr_ptr + state.last_match_len;
4248
4249 found = text_position_next(&state);
4250 if (found)
4252 }
4253 while (found);
4254
4255 /* copy trailing data */
4256 chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4257 appendBinaryStringInfo(&str, start_ptr, chunk_len);
4258
4260
4261 ret_text = cstring_to_text_with_len(str.data, str.len);
4262 pfree(str.data);
4263
4264 PG_RETURN_TEXT_P(ret_text);
4265}
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311
static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state)
Definition: varlena.c:1230
static void text_position_cleanup(TextPositionState *state)
Definition: varlena.c:1574
static void appendStringInfoText(StringInfo str, const text *t)
Definition: varlena.c:4184
static char * text_position_get_match_ptr(TextPositionState *state)
Definition: varlena.c:1539
static bool text_position_next(TextPositionState *state)
Definition: varlena.c:1351

References appendBinaryStringInfo(), appendStringInfoText(), CHECK_FOR_INTERRUPTS, cstring_to_text_with_len(), initStringInfo(), pfree(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, 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 appendStringInfoRegexpSubstr(), check_replace_text_has_escape(), execute_extension_script(), and replace_text_regexp().

◆ replace_text_regexp()

text * replace_text_regexp ( text src_text,
text pattern_text,
text replace_text,
int  cflags,
Oid  collation,
int  search_start,
int  n 
)

Definition at line 4408 of file varlena.c.

4412{
4413 text *ret_text;
4414 regex_t *re;
4415 int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4416 int nmatches = 0;
4418 regmatch_t pmatch[10]; /* main match, plus \1 to \9 */
4419 int nmatch = lengthof(pmatch);
4420 pg_wchar *data;
4421 size_t data_len;
4422 int data_pos;
4423 char *start_ptr;
4424 int escape_status;
4425
4427
4428 /* Convert data string to wide characters. */
4429 data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4430 data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4431
4432 /* Check whether replace_text has escapes, especially regexp submatches. */
4434
4435 /* If no regexp submatches, we can use REG_NOSUB. */
4436 if (escape_status < 2)
4437 {
4438 cflags |= REG_NOSUB;
4439 /* Also tell pg_regexec we only want the whole-match location. */
4440 nmatch = 1;
4441 }
4442
4443 /* Prepare the regexp. */
4444 re = RE_compile_and_cache(pattern_text, cflags, collation);
4445
4446 /* start_ptr points to the data_pos'th character of src_text */
4447 start_ptr = (char *) VARDATA_ANY(src_text);
4448 data_pos = 0;
4449
4450 while (search_start <= data_len)
4451 {
4452 int regexec_result;
4453
4455
4456 regexec_result = pg_regexec(re,
4457 data,
4458 data_len,
4459 search_start,
4460 NULL, /* no details */
4461 nmatch,
4462 pmatch,
4463 0);
4464
4465 if (regexec_result == REG_NOMATCH)
4466 break;
4467
4468 if (regexec_result != REG_OKAY)
4469 {
4470 char errMsg[100];
4471
4472 pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4473 ereport(ERROR,
4474 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4475 errmsg("regular expression failed: %s", errMsg)));
4476 }
4477
4478 /*
4479 * Count matches, and decide whether to replace this match.
4480 */
4481 nmatches++;
4482 if (n > 0 && nmatches != n)
4483 {
4484 /*
4485 * No, so advance search_start, but not start_ptr/data_pos. (Thus,
4486 * we treat the matched text as if it weren't matched, and copy it
4487 * to the output later.)
4488 */
4489 search_start = pmatch[0].rm_eo;
4490 if (pmatch[0].rm_so == pmatch[0].rm_eo)
4491 search_start++;
4492 continue;
4493 }
4494
4495 /*
4496 * Copy the text to the left of the match position. Note we are given
4497 * character not byte indexes.
4498 */
4499 if (pmatch[0].rm_so - data_pos > 0)
4500 {
4501 int chunk_len;
4502
4503 chunk_len = charlen_to_bytelen(start_ptr,
4504 pmatch[0].rm_so - data_pos);
4505 appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4506
4507 /*
4508 * Advance start_ptr over that text, to avoid multiple rescans of
4509 * it if the replace_text contains multiple back-references.
4510 */
4511 start_ptr += chunk_len;
4512 data_pos = pmatch[0].rm_so;
4513 }
4514
4515 /*
4516 * Copy the replace_text, processing escapes if any are present.
4517 */
4518 if (escape_status > 0)
4520 start_ptr, data_pos);
4521 else
4523
4524 /* Advance start_ptr and data_pos over the matched text. */
4525 start_ptr += charlen_to_bytelen(start_ptr,
4526 pmatch[0].rm_eo - data_pos);
4527 data_pos = pmatch[0].rm_eo;
4528
4529 /*
4530 * If we only want to replace one occurrence, we're done.
4531 */
4532 if (n > 0)
4533 break;
4534
4535 /*
4536 * Advance search position. Normally we start the next search at the
4537 * end of the previous match; but if the match was of zero length, we
4538 * have to advance by one character, or we'd just find the same match
4539 * again.
4540 */
4541 search_start = data_pos;
4542 if (pmatch[0].rm_so == pmatch[0].rm_eo)
4543 search_start++;
4544 }
4545
4546 /*
4547 * Copy the text to the right of the last match.
4548 */
4549 if (data_pos < data_len)
4550 {
4551 int chunk_len;
4552
4553 chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4554 appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4555 }
4556
4557 ret_text = cstring_to_text_with_len(buf.data, buf.len);
4558 pfree(buf.data);
4559 pfree(data);
4560
4561 return ret_text;
4562}
#define lengthof(array)
Definition: c.h:759
unsigned int pg_wchar
Definition: mbprint.c:31
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition: mbutils.c:986
const void * data
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
Definition: regerror.c:60
#define REG_NOMATCH
Definition: regex.h:216
#define regmatch_t
Definition: regex.h:246
#define REG_OKAY
Definition: regex.h:215
#define REG_NOSUB
Definition: regex.h:185
#define regex_t
Definition: regex.h:245
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:185
regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation)
Definition: regexp.c:141
static int check_replace_text_has_escape(const text *replace_text)
Definition: varlena.c:4275
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4308

References appendBinaryStringInfo(), appendStringInfoRegexpSubstr(), appendStringInfoText(), buf, charlen_to_bytelen(), CHECK_FOR_INTERRUPTS, check_replace_text_has_escape(), cstring_to_text_with_len(), data, ereport, errcode(), errmsg(), ERROR, initStringInfo(), lengthof, palloc(), pfree(), pg_mb2wchar_with_len(), pg_regerror(), pg_regexec(), RE_compile_and_cache(), REG_NOMATCH, REG_NOSUB, REG_OKAY, regex_t, regmatch_t, replace_text(), VARDATA_ANY, VARSIZE_ANY, and VARSIZE_ANY_EXHDR.

Referenced by textregexreplace(), textregexreplace_extended(), and textregexreplace_noopt().

◆ rest_of_char_same()

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

Definition at line 6354 of file varlena.c.

6355{
6356 while (len > 0)
6357 {
6358 len--;
6359 if (s1[len] != s2[len])
6360 return false;
6361 }
6362 return true;
6363}

References len, s1, and s2.

Referenced by varstr_levenshtein().

◆ split_part()

Datum split_part ( PG_FUNCTION_ARGS  )

Definition at line 4570 of file varlena.c.

4571{
4572 text *inputstring = PG_GETARG_TEXT_PP(0);
4573 text *fldsep = PG_GETARG_TEXT_PP(1);
4574 int fldnum = PG_GETARG_INT32(2);
4575 int inputstring_len;
4576 int fldsep_len;
4578 char *start_ptr;
4579 char *end_ptr;
4580 text *result_text;
4581 bool found;
4582
4583 /* field number is 1 based */
4584 if (fldnum == 0)
4585 ereport(ERROR,
4586 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4587 errmsg("field position must not be zero")));
4588
4589 inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4590 fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4591
4592 /* return empty string for empty input string */
4593 if (inputstring_len < 1)
4595
4596 /* handle empty field separator */
4597 if (fldsep_len < 1)
4598 {
4599 /* if first or last field, return input string, else empty string */
4600 if (fldnum == 1 || fldnum == -1)
4601 PG_RETURN_TEXT_P(inputstring);
4602 else
4604 }
4605
4606 /* find the first field separator */
4607 text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4608
4609 found = text_position_next(&state);
4610
4611 /* special case if fldsep not found at all */
4612 if (!found)
4613 {
4615 /* if first or last field, return input string, else empty string */
4616 if (fldnum == 1 || fldnum == -1)
4617 PG_RETURN_TEXT_P(inputstring);
4618 else
4620 }
4621
4622 /*
4623 * take care of a negative field number (i.e. count from the right) by
4624 * converting to a positive field number; we need total number of fields
4625 */
4626 if (fldnum < 0)
4627 {
4628 /* we found a fldsep, so there are at least two fields */
4629 int numfields = 2;
4630
4631 while (text_position_next(&state))
4632 numfields++;
4633
4634 /* special case of last field does not require an extra pass */
4635 if (fldnum == -1)
4636 {
4637 start_ptr = text_position_get_match_ptr(&state) + state.last_match_len;
4638 end_ptr = VARDATA_ANY(inputstring) + inputstring_len;
4641 end_ptr - start_ptr));
4642 }
4643
4644 /* else, convert fldnum to positive notation */
4645 fldnum += numfields + 1;
4646
4647 /* if nonexistent field, return empty string */
4648 if (fldnum <= 0)
4649 {
4652 }
4653
4654 /* reset to pointing at first match, but now with positive fldnum */
4656 found = text_position_next(&state);
4657 Assert(found);
4658 }
4659
4660 /* identify bounds of first field */
4661 start_ptr = VARDATA_ANY(inputstring);
4663
4664 while (found && --fldnum > 0)
4665 {
4666 /* identify bounds of next field */
4667 start_ptr = end_ptr + state.last_match_len;
4668 found = text_position_next(&state);
4669 if (found)
4671 }
4672
4674
4675 if (fldnum > 0)
4676 {
4677 /* N'th field separator not found */
4678 /* if last field requested, return it, else empty string */
4679 if (fldnum == 1)
4680 {
4681 int last_len = start_ptr - VARDATA_ANY(inputstring);
4682
4683 result_text = cstring_to_text_with_len(start_ptr,
4684 inputstring_len - last_len);
4685 }
4686 else
4687 result_text = cstring_to_text("");
4688 }
4689 else
4690 {
4691 /* non-last field requested */
4692 result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4693 }
4694
4695 PG_RETURN_TEXT_P(result_text);
4696}
static void text_position_reset(TextPositionState *state)
Definition: varlena.c:1566

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.

◆ split_text()

static bool split_text ( FunctionCallInfo  fcinfo,
SplitTextOutputData tstate 
)
static

Definition at line 4793 of file varlena.c.

4794{
4795 text *inputstring;
4796 text *fldsep;
4797 text *null_string;
4798 Oid collation = PG_GET_COLLATION();
4799 int inputstring_len;
4800 int fldsep_len;
4801 char *start_ptr;
4802 text *result_text;
4803
4804 /* when input string is NULL, then result is NULL too */
4805 if (PG_ARGISNULL(0))
4806 return false;
4807
4808 inputstring = PG_GETARG_TEXT_PP(0);
4809
4810 /* fldsep can be NULL */
4811 if (!PG_ARGISNULL(1))
4812 fldsep = PG_GETARG_TEXT_PP(1);
4813 else
4814 fldsep = NULL;
4815
4816 /* null_string can be NULL or omitted */
4817 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
4818 null_string = PG_GETARG_TEXT_PP(2);
4819 else
4820 null_string = NULL;
4821
4822 if (fldsep != NULL)
4823 {
4824 /*
4825 * Normal case with non-null fldsep. Use the text_position machinery
4826 * to search for occurrences of fldsep.
4827 */
4829
4830 inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4831 fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4832
4833 /* return empty set for empty input string */
4834 if (inputstring_len < 1)
4835 return true;
4836
4837 /* empty field separator: return input string as a one-element set */
4838 if (fldsep_len < 1)
4839 {
4840 split_text_accum_result(tstate, inputstring,
4841 null_string, collation);
4842 return true;
4843 }
4844
4845 text_position_setup(inputstring, fldsep, collation, &state);
4846
4847 start_ptr = VARDATA_ANY(inputstring);
4848
4849 for (;;)
4850 {
4851 bool found;
4852 char *end_ptr;
4853 int chunk_len;
4854
4856
4857 found = text_position_next(&state);
4858 if (!found)
4859 {
4860 /* fetch last field */
4861 chunk_len = ((char *) inputstring + VARSIZE_ANY(inputstring)) - start_ptr;
4862 end_ptr = NULL; /* not used, but some compilers complain */
4863 }
4864 else
4865 {
4866 /* fetch non-last field */
4868 chunk_len = end_ptr - start_ptr;
4869 }
4870
4871 /* build a temp text datum to pass to split_text_accum_result */
4872 result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4873
4874 /* stash away this field */
4875 split_text_accum_result(tstate, result_text,
4876 null_string, collation);
4877
4878 pfree(result_text);
4879
4880 if (!found)
4881 break;
4882
4883 start_ptr = end_ptr + state.last_match_len;
4884 }
4885
4887 }
4888 else
4889 {
4890 /*
4891 * When fldsep is NULL, each character in the input string becomes a
4892 * separate element in the result set. The separator is effectively
4893 * the space between characters.
4894 */
4895 inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4896
4897 start_ptr = VARDATA_ANY(inputstring);
4898
4899 while (inputstring_len > 0)
4900 {
4901 int chunk_len = pg_mblen(start_ptr);
4902
4904
4905 /* build a temp text datum to pass to split_text_accum_result */
4906 result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4907
4908 /* stash away this field */
4909 split_text_accum_result(tstate, result_text,
4910 null_string, collation);
4911
4912 pfree(result_text);
4913
4914 start_ptr += chunk_len;
4915 inputstring_len -= chunk_len;
4916 }
4917 }
4918
4919 return true;
4920}
static void split_text_accum_result(SplitTextOutputData *tstate, text *field_value, text *null_string, Oid collation)
Definition: varlena.c:4929

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

◆ split_text_accum_result()

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

Definition at line 4929 of file varlena.c.

4933{
4934 bool is_null = false;
4935
4936 if (null_string && text_isequal(field_value, null_string, collation))
4937 is_null = true;
4938
4939 if (tstate->tupstore)
4940 {
4941 Datum values[1];
4942 bool nulls[1];
4943
4944 values[0] = PointerGetDatum(field_value);
4945 nulls[0] = is_null;
4946
4948 tstate->tupdesc,
4949 values,
4950 nulls);
4951 }
4952 else
4953 {
4954 tstate->astate = accumArrayResult(tstate->astate,
4955 PointerGetDatum(field_value),
4956 is_null,
4957 TEXTOID,
4959 }
4960}
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5350
static Datum values[MAXATTR]
Definition: bootstrap.c:151
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
TupleDesc tupdesc
Definition: varlena.c:115
ArrayBuildState * astate
Definition: varlena.c:113
Tuplestorestate * tupstore
Definition: varlena.c:114
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784
static bool text_isequal(text *txt1, text *txt2, Oid collid)
Definition: varlena.c:4702

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

Referenced by split_text().

◆ SplitDirectoriesString()

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

Definition at line 3652 of file varlena.c.

3654{
3655 char *nextp = rawstring;
3656 bool done = false;
3657
3658 *namelist = NIL;
3659
3660 while (scanner_isspace(*nextp))
3661 nextp++; /* skip leading whitespace */
3662
3663 if (*nextp == '\0')
3664 return true; /* allow empty string */
3665
3666 /* At the top of the loop, we are at start of a new directory. */
3667 do
3668 {
3669 char *curname;
3670 char *endp;
3671
3672 if (*nextp == '"')
3673 {
3674 /* Quoted name --- collapse quote-quote pairs */
3675 curname = nextp + 1;
3676 for (;;)
3677 {
3678 endp = strchr(nextp + 1, '"');
3679 if (endp == NULL)
3680 return false; /* mismatched quotes */
3681 if (endp[1] != '"')
3682 break; /* found end of quoted name */
3683 /* Collapse adjacent quotes into one quote, and look again */
3684 memmove(endp, endp + 1, strlen(endp));
3685 nextp = endp;
3686 }
3687 /* endp now points at the terminating quote */
3688 nextp = endp + 1;
3689 }
3690 else
3691 {
3692 /* Unquoted name --- extends to separator or end of string */
3693 curname = endp = nextp;
3694 while (*nextp && *nextp != separator)
3695 {
3696 /* trailing whitespace should not be included in name */
3697 if (!scanner_isspace(*nextp))
3698 endp = nextp + 1;
3699 nextp++;
3700 }
3701 if (curname == endp)
3702 return false; /* empty unquoted name not allowed */
3703 }
3704
3705 while (scanner_isspace(*nextp))
3706 nextp++; /* skip trailing whitespace */
3707
3708 if (*nextp == separator)
3709 {
3710 nextp++;
3711 while (scanner_isspace(*nextp))
3712 nextp++; /* skip leading whitespace for next */
3713 /* we expect another name, so done remains false */
3714 }
3715 else if (*nextp == '\0')
3716 done = true;
3717 else
3718 return false; /* invalid syntax */
3719
3720 /* Now safe to overwrite separator with a null */
3721 *endp = '\0';
3722
3723 /* Truncate path if it's overlength */
3724 if (strlen(curname) >= MAXPGPATH)
3725 curname[MAXPGPATH - 1] = '\0';
3726
3727 /*
3728 * Finished isolating current name --- add it to list
3729 */
3730 curname = pstrdup(curname);
3731 canonicalize_path(curname);
3732 *namelist = lappend(*namelist, curname);
3733
3734 /* Loop back if we didn't reach end of string */
3735 } while (!done);
3736
3737 return true;
3738}
List * lappend(List *list, void *datum)
Definition: list.c:339
char * pstrdup(const char *in)
Definition: mcxt.c:1699
#define MAXPGPATH
#define NIL
Definition: pg_list.h:68
void canonicalize_path(char *path)
Definition: path.c:337
bool scanner_isspace(char ch)
Definition: scansup.c:117

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

Referenced by check_oauth_validator(), load_libraries(), and PostmasterMain().

◆ SplitGUCList()

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

Definition at line 3773 of file varlena.c.

3775{
3776 char *nextp = rawstring;
3777 bool done = false;
3778
3779 *namelist = NIL;
3780
3781 while (scanner_isspace(*nextp))
3782 nextp++; /* skip leading whitespace */
3783
3784 if (*nextp == '\0')
3785 return true; /* allow empty string */
3786
3787 /* At the top of the loop, we are at start of a new identifier. */
3788 do
3789 {
3790 char *curname;
3791 char *endp;
3792
3793 if (*nextp == '"')
3794 {
3795 /* Quoted name --- collapse quote-quote pairs */
3796 curname = nextp + 1;
3797 for (;;)
3798 {
3799 endp = strchr(nextp + 1, '"');
3800 if (endp == NULL)
3801 return false; /* mismatched quotes */
3802 if (endp[1] != '"')
3803 break; /* found end of quoted name */
3804 /* Collapse adjacent quotes into one quote, and look again */
3805 memmove(endp, endp + 1, strlen(endp));
3806 nextp = endp;
3807 }
3808 /* endp now points at the terminating quote */
3809 nextp = endp + 1;
3810 }
3811 else
3812 {
3813 /* Unquoted name --- extends to separator or whitespace */
3814 curname = nextp;
3815 while (*nextp && *nextp != separator &&
3816 !scanner_isspace(*nextp))
3817 nextp++;
3818 endp = nextp;
3819 if (curname == nextp)
3820 return false; /* empty unquoted name not allowed */
3821 }
3822
3823 while (scanner_isspace(*nextp))
3824 nextp++; /* skip trailing whitespace */
3825
3826 if (*nextp == separator)
3827 {
3828 nextp++;
3829 while (scanner_isspace(*nextp))
3830 nextp++; /* skip leading whitespace for next */
3831 /* we expect another name, so done remains false */
3832 }
3833 else if (*nextp == '\0')
3834 done = true;
3835 else
3836 return false; /* invalid syntax */
3837
3838 /* Now safe to overwrite separator with a null */
3839 *endp = '\0';
3840
3841 /*
3842 * Finished isolating current name --- add it to list
3843 */
3844 *namelist = lappend(*namelist, curname);
3845
3846 /* Loop back if we didn't reach end of string */
3847 } while (!done);
3848
3849 return true;
3850}

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

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

◆ SplitIdentifierString()

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

Definition at line 3525 of file varlena.c.

3527{
3528 char *nextp = rawstring;
3529 bool done = false;
3530
3531 *namelist = NIL;
3532
3533 while (scanner_isspace(*nextp))
3534 nextp++; /* skip leading whitespace */
3535
3536 if (*nextp == '\0')
3537 return true; /* allow empty string */
3538
3539 /* At the top of the loop, we are at start of a new identifier. */
3540 do
3541 {
3542 char *curname;
3543 char *endp;
3544
3545 if (*nextp == '"')
3546 {
3547 /* Quoted name --- collapse quote-quote pairs, no downcasing */
3548 curname = nextp + 1;
3549 for (;;)
3550 {
3551 endp = strchr(nextp + 1, '"');
3552 if (endp == NULL)
3553 return false; /* mismatched quotes */
3554 if (endp[1] != '"')
3555 break; /* found end of quoted name */
3556 /* Collapse adjacent quotes into one quote, and look again */
3557 memmove(endp, endp + 1, strlen(endp));
3558 nextp = endp;
3559 }
3560 /* endp now points at the terminating quote */
3561 nextp = endp + 1;
3562 }
3563 else
3564 {
3565 /* Unquoted name --- extends to separator or whitespace */
3566 char *downname;
3567 int len;
3568
3569 curname = nextp;
3570 while (*nextp && *nextp != separator &&
3571 !scanner_isspace(*nextp))
3572 nextp++;
3573 endp = nextp;
3574 if (curname == nextp)
3575 return false; /* empty unquoted name not allowed */
3576
3577 /*
3578 * Downcase the identifier, using same code as main lexer does.
3579 *
3580 * XXX because we want to overwrite the input in-place, we cannot
3581 * support a downcasing transformation that increases the string
3582 * length. This is not a problem given the current implementation
3583 * of downcase_truncate_identifier, but we'll probably have to do
3584 * something about this someday.
3585 */
3586 len = endp - curname;
3587 downname = downcase_truncate_identifier(curname, len, false);
3588 Assert(strlen(downname) <= len);
3589 strncpy(curname, downname, len); /* strncpy is required here */
3590 pfree(downname);
3591 }
3592
3593 while (scanner_isspace(*nextp))
3594 nextp++; /* skip trailing whitespace */
3595
3596 if (*nextp == separator)
3597 {
3598 nextp++;
3599 while (scanner_isspace(*nextp))
3600 nextp++; /* skip leading whitespace for next */
3601 /* we expect another name, so done remains false */
3602 }
3603 else if (*nextp == '\0')
3604 done = true;
3605 else
3606 return false; /* invalid syntax */
3607
3608 /* Now safe to overwrite separator with a null */
3609 *endp = '\0';
3610
3611 /* Truncate name if it's overlength */
3612 truncate_identifier(curname, strlen(curname), false);
3613
3614 /*
3615 * Finished isolating current name --- add it to list
3616 */
3617 *namelist = lappend(*namelist, curname);
3618
3619 /* Loop back if we didn't reach end of string */
3620 } while (!done);
3621
3622 return true;
3623}
void truncate_identifier(char *ident, int len, bool warn)
Definition: scansup.c:93
char * downcase_truncate_identifier(const char *ident, int len, bool warn)
Definition: scansup.c:37

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

Referenced by check_createrole_self_grant(), check_datestyle(), check_log_connections(), check_log_destination(), check_restrict_nonsystem_relation_kind(), 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(), preprocessNamespacePath(), stringToQualifiedNameList(), textToQualifiedNameList(), and validate_sync_standby_slots().

◆ string_agg_combine()

Datum string_agg_combine ( PG_FUNCTION_ARGS  )

Definition at line 5443 of file varlena.c.

5444{
5445 StringInfo state1;
5446 StringInfo state2;
5447 MemoryContext agg_context;
5448
5449 if (!AggCheckCallContext(fcinfo, &agg_context))
5450 elog(ERROR, "aggregate function called in non-aggregate context");
5451
5452 state1 = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5453 state2 = PG_ARGISNULL(1) ? NULL : (StringInfo) PG_GETARG_POINTER(1);
5454
5455 if (state2 == NULL)
5456 {
5457 /*
5458 * NULL state2 is easy, just return state1, which we know is already
5459 * in the agg_context
5460 */
5461 if (state1 == NULL)
5463 PG_RETURN_POINTER(state1);
5464 }
5465
5466 if (state1 == NULL)
5467 {
5468 /* We must copy state2's data into the agg_context */
5469 MemoryContext old_context;
5470
5471 old_context = MemoryContextSwitchTo(agg_context);
5472 state1 = makeStringAggState(fcinfo);
5473 appendBinaryStringInfo(state1, state2->data, state2->len);
5474 state1->cursor = state2->cursor;
5475 MemoryContextSwitchTo(old_context);
5476 }
5477 else if (state2->len > 0)
5478 {
5479 /* Combine ... state1->cursor does not change in this case */
5480 appendBinaryStringInfo(state1, state2->data, state2->len);
5481 }
5482
5483 PG_RETURN_POINTER(state1);
5484}

References AggCheckCallContext(), appendBinaryStringInfo(), StringInfoData::cursor, StringInfoData::data, elog, ERROR, StringInfoData::len, makeStringAggState(), MemoryContextSwitchTo(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, and PG_RETURN_POINTER.

◆ string_agg_deserialize()

Datum string_agg_deserialize ( PG_FUNCTION_ARGS  )

Definition at line 5524 of file varlena.c.

5525{
5526 bytea *sstate;
5527 StringInfo result;
5529 char *data;
5530 int datalen;
5531
5532 /* cannot be called directly because of internal-type argument */
5533 Assert(AggCheckCallContext(fcinfo, NULL));
5534
5535 sstate = PG_GETARG_BYTEA_PP(0);
5536
5537 /*
5538 * Initialize a StringInfo so that we can "receive" it using the standard
5539 * recv-function infrastructure.
5540 */
5542 VARSIZE_ANY_EXHDR(sstate));
5543
5544 result = makeStringAggState(fcinfo);
5545
5546 /* cursor */
5547 result->cursor = pq_getmsgint(&buf, 4);
5548
5549 /* data */
5550 datalen = VARSIZE_ANY_EXHDR(sstate) - 4;
5551 data = (char *) pq_getmsgbytes(&buf, datalen);
5552 appendBinaryStringInfo(result, data, datalen);
5553
5554 pq_getmsgend(&buf);
5555
5556 PG_RETURN_POINTER(result);
5557}
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:635
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:508
static void initReadOnlyStringInfo(StringInfo str, char *data, int len)
Definition: stringinfo.h:157

References AggCheckCallContext(), appendBinaryStringInfo(), Assert(), buf, StringInfoData::cursor, data, initReadOnlyStringInfo(), makeStringAggState(), PG_GETARG_BYTEA_PP, PG_RETURN_POINTER, pq_getmsgbytes(), pq_getmsgend(), pq_getmsgint(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ string_agg_finalfn()

Datum string_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 5560 of file varlena.c.

5561{
5563
5564 /* cannot be called directly because of internal-type argument */
5565 Assert(AggCheckCallContext(fcinfo, NULL));
5566
5568
5569 if (state != NULL)
5570 {
5571 /* As per comment in transfn, strip data before the cursor position */
5573 state->len - state->cursor));
5574 }
5575 else
5577}

References AggCheckCallContext(), Assert(), cstring_to_text_with_len(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_NULL, and PG_RETURN_TEXT_P.

◆ string_agg_serialize()

Datum string_agg_serialize ( PG_FUNCTION_ARGS  )

Definition at line 5493 of file varlena.c.

5494{
5497 bytea *result;
5498
5499 /* cannot be called directly because of internal-type argument */
5500 Assert(AggCheckCallContext(fcinfo, NULL));
5501
5503
5505
5506 /* cursor */
5507 pq_sendint(&buf, state->cursor, 4);
5508
5509 /* data */
5510 pq_sendbytes(&buf, state->data, state->len);
5511
5512 result = pq_endtypsend(&buf);
5513
5514 PG_RETURN_BYTEA_P(result);
5515}
void pq_sendbytes(StringInfo buf, const void *data, int datalen)
Definition: pqformat.c:126
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendint(StringInfo buf, uint32 i, int b)
Definition: pqformat.h:171

References AggCheckCallContext(), Assert(), buf, PG_GETARG_POINTER, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendbytes(), and pq_sendint().

◆ string_agg_transfn()

Datum string_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 5388 of file varlena.c.

5389{
5391
5393
5394 /* Append the value unless null, preceding it with the delimiter. */
5395 if (!PG_ARGISNULL(1))
5396 {
5398 bool isfirst = false;
5399
5400 /*
5401 * You might think we can just throw away the first delimiter, however
5402 * we must keep it as we may be a parallel worker doing partial
5403 * aggregation building a state to send to the main process. We need
5404 * to keep the delimiter of every aggregation so that the combine
5405 * function can properly join up the strings of two separately
5406 * partially aggregated results. The first delimiter is only stripped
5407 * off in the final function. To know how much to strip off the front
5408 * of the string, we store the length of the first delimiter in the
5409 * StringInfo's cursor field, which we don't otherwise need here.
5410 */
5411 if (state == NULL)
5412 {
5413 state = makeStringAggState(fcinfo);
5414 isfirst = true;
5415 }
5416
5417 if (!PG_ARGISNULL(2))
5418 {
5419 text *delim = PG_GETARG_TEXT_PP(2);
5420
5422 if (isfirst)
5423 state->cursor = VARSIZE_ANY_EXHDR(delim);
5424 }
5425
5427 }
5428
5429 /*
5430 * The transition type for string_agg() is declared to be "internal",
5431 * which is a pass-by-value type the same size as a pointer.
5432 */
5433 if (state)
5436}

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

◆ text_catenate()

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

Definition at line 773 of file varlena.c.

774{
775 text *result;
776 int len1,
777 len2,
778 len;
779 char *ptr;
780
781 len1 = VARSIZE_ANY_EXHDR(t1);
782 len2 = VARSIZE_ANY_EXHDR(t2);
783
784 /* paranoia ... probably should throw error instead? */
785 if (len1 < 0)
786 len1 = 0;
787 if (len2 < 0)
788 len2 = 0;
789
790 len = len1 + len2 + VARHDRSZ;
791 result = (text *) palloc(len);
792
793 /* Set size of result string... */
794 SET_VARSIZE(result, len);
795
796 /* Fill data field of result string... */
797 ptr = VARDATA(result);
798 if (len1 > 0)
799 memcpy(ptr, VARDATA_ANY(t1), len1);
800 if (len2 > 0)
801 memcpy(ptr + len1, VARDATA_ANY(t2), len2);
802
803 return result;
804}

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

Referenced by text_overlay(), and textcat().

◆ text_cmp()

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

Definition at line 1658 of file varlena.c.

1659{
1660 char *a1p,
1661 *a2p;
1662 int len1,
1663 len2;
1664
1665 a1p = VARDATA_ANY(arg1);
1666 a2p = VARDATA_ANY(arg2);
1667
1668 len1 = VARSIZE_ANY_EXHDR(arg1);
1669 len2 = VARSIZE_ANY_EXHDR(arg2);
1670
1671 return varstr_cmp(a1p, len1, a2p, len2, collid);
1672}

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

◆ text_concat()

Datum text_concat ( PG_FUNCTION_ARGS  )

Definition at line 5704 of file varlena.c.

5705{
5706 text *result;
5707
5708 result = concat_internal("", 0, fcinfo);
5709 if (result == NULL)
5711 PG_RETURN_TEXT_P(result);
5712}
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5624

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5719 of file varlena.c.

5720{
5721 char *sep;
5722 text *result;
5723
5724 /* return NULL when separator is NULL */
5725 if (PG_ARGISNULL(0))
5728
5729 result = concat_internal(sep, 1, fcinfo);
5730 if (result == NULL)
5732 PG_RETURN_TEXT_P(result);
5733}

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

◆ text_format()

Datum text_format ( PG_FUNCTION_ARGS  )

Definition at line 5840 of file varlena.c.

5841{
5842 text *fmt;
5844 const char *cp;
5845 const char *start_ptr;
5846 const char *end_ptr;
5847 text *result;
5848 int arg;
5849 bool funcvariadic;
5850 int nargs;
5851 Datum *elements = NULL;
5852 bool *nulls = NULL;
5853 Oid element_type = InvalidOid;
5854 Oid prev_type = InvalidOid;
5855 Oid prev_width_type = InvalidOid;
5856 FmgrInfo typoutputfinfo;
5857 FmgrInfo typoutputinfo_width;
5858
5859 /* When format string is null, immediately return null */
5860 if (PG_ARGISNULL(0))
5862
5863 /* If argument is marked VARIADIC, expand array into elements */
5864 if (get_fn_expr_variadic(fcinfo->flinfo))
5865 {
5866 ArrayType *arr;
5867 int16 elmlen;
5868 bool elmbyval;
5869 char elmalign;
5870 int nitems;
5871
5872 /* Should have just the one argument */
5873 Assert(PG_NARGS() == 2);
5874
5875 /* If argument is NULL, we treat it as zero-length array */
5876 if (PG_ARGISNULL(1))
5877 nitems = 0;
5878 else
5879 {
5880 /*
5881 * Non-null argument had better be an array. We assume that any
5882 * call context that could let get_fn_expr_variadic return true
5883 * will have checked that a VARIADIC-labeled parameter actually is
5884 * an array. So it should be okay to just Assert that it's an
5885 * array rather than doing a full-fledged error check.
5886 */
5888
5889 /* OK, safe to fetch the array value */
5890 arr = PG_GETARG_ARRAYTYPE_P(1);
5891
5892 /* Get info about array element type */
5893 element_type = ARR_ELEMTYPE(arr);
5894 get_typlenbyvalalign(element_type,
5895 &elmlen, &elmbyval, &elmalign);
5896
5897 /* Extract all array elements */
5898 deconstruct_array(arr, element_type, elmlen, elmbyval, elmalign,
5899 &elements, &nulls, &nitems);
5900 }
5901
5902 nargs = nitems + 1;
5903 funcvariadic = true;
5904 }
5905 else
5906 {
5907 /* Non-variadic case, we'll process the arguments individually */
5908 nargs = PG_NARGS();
5909 funcvariadic = false;
5910 }
5911
5912 /* Setup for main loop. */
5913 fmt = PG_GETARG_TEXT_PP(0);
5914 start_ptr = VARDATA_ANY(fmt);
5915 end_ptr = start_ptr + VARSIZE_ANY_EXHDR(fmt);
5917 arg = 1; /* next argument position to print */
5918
5919 /* Scan format string, looking for conversion specifiers. */
5920 for (cp = start_ptr; cp < end_ptr; cp++)
5921 {
5922 int argpos;
5923 int widthpos;
5924 int flags;
5925 int width;
5926 Datum value;
5927 bool isNull;
5928 Oid typid;
5929
5930 /*
5931 * If it's not the start of a conversion specifier, just copy it to
5932 * the output buffer.
5933 */
5934 if (*cp != '%')
5935 {
5937 continue;
5938 }
5939
5940 ADVANCE_PARSE_POINTER(cp, end_ptr);
5941
5942 /* Easy case: %% outputs a single % */
5943 if (*cp == '%')
5944 {
5946 continue;
5947 }
5948
5949 /* Parse the optional portions of the format specifier */
5950 cp = text_format_parse_format(cp, end_ptr,
5951 &argpos, &widthpos,
5952 &flags, &width);
5953
5954 /*
5955 * Next we should see the main conversion specifier. Whether or not
5956 * an argument position was present, it's known that at least one
5957 * character remains in the string at this point. Experience suggests
5958 * that it's worth checking that that character is one of the expected
5959 * ones before we try to fetch arguments, so as to produce the least
5960 * confusing response to a mis-formatted specifier.
5961 */
5962 if (strchr("sIL", *cp) == NULL)
5963 ereport(ERROR,
5964 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5965 errmsg("unrecognized format() type specifier \"%.*s\"",
5966 pg_mblen(cp), cp),
5967 errhint("For a single \"%%\" use \"%%%%\".")));
5968
5969 /* If indirect width was specified, get its value */
5970 if (widthpos >= 0)
5971 {
5972 /* Collect the specified or next argument position */
5973 if (widthpos > 0)
5974 arg = widthpos;
5975 if (arg >= nargs)
5976 ereport(ERROR,
5977 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5978 errmsg("too few arguments for format()")));
5979
5980 /* Get the value and type of the selected argument */
5981 if (!funcvariadic)
5982 {
5984 isNull = PG_ARGISNULL(arg);
5985 typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
5986 }
5987 else
5988 {
5989 value = elements[arg - 1];
5990 isNull = nulls[arg - 1];
5991 typid = element_type;
5992 }
5993 if (!OidIsValid(typid))
5994 elog(ERROR, "could not determine data type of format() input");
5995
5996 arg++;
5997
5998 /* We can treat NULL width the same as zero */
5999 if (isNull)
6000 width = 0;
6001 else if (typid == INT4OID)
6002 width = DatumGetInt32(value);
6003 else if (typid == INT2OID)
6004 width = DatumGetInt16(value);
6005 else
6006 {
6007 /* For less-usual datatypes, convert to text then to int */
6008 char *str;
6009
6010 if (typid != prev_width_type)
6011 {
6012 Oid typoutputfunc;
6013 bool typIsVarlena;
6014
6015 getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
6016 fmgr_info(typoutputfunc, &typoutputinfo_width);
6017 prev_width_type = typid;
6018 }
6019
6020 str = OutputFunctionCall(&typoutputinfo_width, value);
6021
6022 /* pg_strtoint32 will complain about bad data or overflow */
6023 width = pg_strtoint32(str);
6024
6025 pfree(str);
6026 }
6027 }
6028
6029 /* Collect the specified or next argument position */
6030 if (argpos > 0)
6031 arg = argpos;
6032 if (arg >= nargs)
6033 ereport(ERROR,
6034 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6035 errmsg("too few arguments for format()")));
6036
6037 /* Get the value and type of the selected argument */
6038 if (!funcvariadic)
6039 {
6041 isNull = PG_ARGISNULL(arg);
6042 typid = get_fn_expr_argtype(fcinfo->flinfo, arg);
6043 }
6044 else
6045 {
6046 value = elements[arg - 1];
6047 isNull = nulls[arg - 1];
6048 typid = element_type;
6049 }
6050 if (!OidIsValid(typid))
6051 elog(ERROR, "could not determine data type of format() input");
6052
6053 arg++;
6054
6055 /*
6056 * Get the appropriate typOutput function, reusing previous one if
6057 * same type as previous argument. That's particularly useful in the
6058 * variadic-array case, but often saves work even for ordinary calls.
6059 */
6060 if (typid != prev_type)
6061 {
6062 Oid typoutputfunc;
6063 bool typIsVarlena;
6064
6065 getTypeOutputInfo(typid, &typoutputfunc, &typIsVarlena);
6066 fmgr_info(typoutputfunc, &typoutputfinfo);
6067 prev_type = typid;
6068 }
6069
6070 /*
6071 * And now we can format the value.
6072 */
6073 switch (*cp)
6074 {
6075 case 's':
6076 case 'I':
6077 case 'L':
6078 text_format_string_conversion(&str, *cp, &typoutputfinfo,
6079 value, isNull,
6080 flags, width);
6081 break;
6082 default:
6083 /* should not get here, because of previous check */
6084 ereport(ERROR,
6085 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6086 errmsg("unrecognized format() type specifier \"%.*s\"",
6087 pg_mblen(cp), cp),
6088 errhint("For a single \"%%\" use \"%%%%\".")));
6089 break;
6090 }
6091 }
6092
6093 /* Don't need deconstruct_array results anymore. */
6094 if (elements != NULL)
6095 pfree(elements);
6096 if (nulls != NULL)
6097 pfree(nulls);
6098
6099 /* Generate results. */
6100 result = cstring_to_text_with_len(str.data, str.len);
6101 pfree(str.data);
6102
6103 PG_RETURN_TEXT_P(result);
6104}
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3631
int16_t int16
Definition: c.h:497
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition: fmgr.c:127
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Definition: lsyscache.c:2354
int32 pg_strtoint32(const char *s)
Definition: numutils.c:383
void * arg
static int16 DatumGetInt16(Datum X)
Definition: postgres.h:167
#define InvalidOid
Definition: postgres_ext.h:35
#define appendStringInfoCharMacro(str, ch)
Definition: stringinfo.h:231
static void text_format_string_conversion(StringInfo buf, char conversion, FmgrInfo *typOutputInfo, Datum value, bool isNull, int flags, int width)
Definition: varlena.c:6243
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:6166
#define ADVANCE_PARSE_POINTER(ptr, end_ptr)
Definition: varlena.c:5827

References ADVANCE_PARSE_POINTER, appendStringInfoCharMacro, arg, ARR_ELEMTYPE, Assert(), cstring_to_text_with_len(), 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, nitems, 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(), str, text_format_parse_format(), text_format_string_conversion(), value, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by text_format_nv().

◆ text_format_append_string()

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

Definition at line 6292 of file varlena.c.

6294{
6295 bool align_to_left = false;
6296 int len;
6297
6298 /* fast path for typical easy case */
6299 if (width == 0)
6300 {
6302 return;
6303 }
6304
6305 if (width < 0)
6306 {
6307 /* Negative width: implicit '-' flag, then take absolute value */
6308 align_to_left = true;
6309 /* -INT_MIN is undefined */
6310 if (width <= INT_MIN)
6311 ereport(ERROR,
6312 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6313 errmsg("number is out of range")));
6314 width = -width;
6315 }
6316 else if (flags & TEXT_FORMAT_FLAG_MINUS)
6317 align_to_left = true;
6318
6319 len = pg_mbstrlen(str);
6320 if (align_to_left)
6321 {
6322 /* left justify */
6324 if (len < width)
6325 appendStringInfoSpaces(buf, width - len);
6326 }
6327 else
6328 {
6329 /* right justify */
6330 if (len < width)
6331 appendStringInfoSpaces(buf, width - len);
6333 }
6334}
int pg_mbstrlen(const char *mbstr)
Definition: mbutils.c:1037
void appendStringInfoSpaces(StringInfo str, int count)
Definition: stringinfo.c:260
#define TEXT_FORMAT_FLAG_MINUS
Definition: varlena.c:5825

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

Referenced by text_format_string_conversion().

◆ text_format_nv()

Datum text_format_nv ( PG_FUNCTION_ARGS  )

Definition at line 6344 of file varlena.c.

6345{
6346 return text_format(fcinfo);
6347}
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5840

References text_format().

◆ text_format_parse_digits()

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

Definition at line 6117 of file varlena.c.

6118{
6119 bool found = false;
6120 const char *cp = *ptr;
6121 int val = 0;
6122
6123 while (*cp >= '0' && *cp <= '9')
6124 {
6125 int8 digit = (*cp - '0');
6126
6127 if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
6129 ereport(ERROR,
6130 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6131 errmsg("number is out of range")));
6132 ADVANCE_PARSE_POINTER(cp, end_ptr);
6133 found = true;
6134 }
6135
6136 *ptr = cp;
6137 *value = val;
6138
6139 return found;
6140}
int8_t int8
Definition: c.h:496
#define unlikely(x)
Definition: c.h:347
static bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
Definition: int.h:187

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

Referenced by text_format_parse_format().

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

6169{
6170 const char *cp = start_ptr;
6171 int n;
6172
6173 /* set defaults for output parameters */
6174 *argpos = -1;
6175 *widthpos = -1;
6176 *flags = 0;
6177 *width = 0;
6178
6179 /* try to identify first number */
6180 if (text_format_parse_digits(&cp, end_ptr, &n))
6181 {
6182 if (*cp != '$')
6183 {
6184 /* Must be just a width and a type, so we're done */
6185 *width = n;
6186 return cp;
6187 }
6188 /* The number was argument position */
6189 *argpos = n;
6190 /* Explicit 0 for argument index is immediately refused */
6191 if (n == 0)
6192 ereport(ERROR,
6193 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6194 errmsg("format specifies argument 0, but arguments are numbered from 1")));
6195 ADVANCE_PARSE_POINTER(cp, end_ptr);
6196 }
6197
6198 /* Handle flags (only minus is supported now) */
6199 while (*cp == '-')
6200 {
6201 *flags |= TEXT_FORMAT_FLAG_MINUS;
6202 ADVANCE_PARSE_POINTER(cp, end_ptr);
6203 }
6204
6205 if (*cp == '*')
6206 {
6207 /* Handle indirect width */
6208 ADVANCE_PARSE_POINTER(cp, end_ptr);
6209 if (text_format_parse_digits(&cp, end_ptr, &n))
6210 {
6211 /* number in this position must be closed by $ */
6212 if (*cp != '$')
6213 ereport(ERROR,
6214 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6215 errmsg("width argument position must be ended by \"$\"")));
6216 /* The number was width argument position */
6217 *widthpos = n;
6218 /* Explicit 0 for argument index is immediately refused */
6219 if (n == 0)
6220 ereport(ERROR,
6221 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6222 errmsg("format specifies argument 0, but arguments are numbered from 1")));
6223 ADVANCE_PARSE_POINTER(cp, end_ptr);
6224 }
6225 else
6226 *widthpos = 0; /* width's argument position is unspecified */
6227 }
6228 else
6229 {
6230 /* Check for direct width specification */
6231 if (text_format_parse_digits(&cp, end_ptr, &n))
6232 *width = n;
6233 }
6234
6235 /* cp should now be pointing at type character */
6236 return cp;
6237}
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:6117

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

Referenced by text_format().

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

6247{
6248 char *str;
6249
6250 /* Handle NULL arguments before trying to stringify the value. */
6251 if (isNull)
6252 {
6253 if (conversion == 's')
6254 text_format_append_string(buf, "", flags, width);
6255 else if (conversion == 'L')
6256 text_format_append_string(buf, "NULL", flags, width);
6257 else if (conversion == 'I')
6258 ereport(ERROR,
6259 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6260 errmsg("null values cannot be formatted as an SQL identifier")));
6261 return;
6262 }
6263
6264 /* Stringify. */
6265 str = OutputFunctionCall(typOutputInfo, value);
6266
6267 /* Escape. */
6268 if (conversion == 'I')
6269 {
6270 /* quote_identifier may or may not allocate a new string. */
6272 }
6273 else if (conversion == 'L')
6274 {
6275 char *qstr = quote_literal_cstr(str);
6276
6277 text_format_append_string(buf, qstr, flags, width);
6278 /* quote_literal_cstr() always allocates a new string */
6279 pfree(qstr);
6280 }
6281 else
6282 text_format_append_string(buf, str, flags, width);
6283
6284 /* Cleanup. */
6285 pfree(str);
6286}
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:103
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:13019
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:6292

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

Referenced by text_format().

◆ text_ge()

Datum text_ge ( PG_FUNCTION_ARGS  )

Definition at line 1832 of file varlena.c.

1833{
1834 text *arg1 = PG_GETARG_TEXT_PP(0);
1835 text *arg2 = PG_GETARG_TEXT_PP(1);
1836 bool result;
1837
1838 result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) >= 0);
1839
1840 PG_FREE_IF_COPY(arg1, 0);
1841 PG_FREE_IF_COPY(arg2, 1);
1842
1843 PG_RETURN_BOOL(result);
1844}

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

Referenced by gbt_textge().

◆ text_gt()

Datum text_gt ( PG_FUNCTION_ARGS  )

Definition at line 1817 of file varlena.c.

1818{
1819 text *arg1 = PG_GETARG_TEXT_PP(0);
1820 text *arg2 = PG_GETARG_TEXT_PP(1);
1821 bool result;
1822
1823 result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0);
1824
1825 PG_FREE_IF_COPY(arg1, 0);
1826 PG_FREE_IF_COPY(arg2, 1);
1827
1828 PG_RETURN_BOOL(result);
1829}

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

Referenced by gbt_textgt().

◆ text_isequal()

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

Definition at line 4702 of file varlena.c.

4703{
4705 collid,
4706 PointerGetDatum(txt1),
4707 PointerGetDatum(txt2)));
4708}
static bool DatumGetBool(Datum X)
Definition: postgres.h:95
Datum texteq(PG_FUNCTION_ARGS)
Definition: varlena.c:1683

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

Referenced by split_text_accum_result().

◆ text_larger()

Datum text_larger ( PG_FUNCTION_ARGS  )

Definition at line 2618 of file varlena.c.

2619{
2620 text *arg1 = PG_GETARG_TEXT_PP(0);
2621 text *arg2 = PG_GETARG_TEXT_PP(1);
2622 text *result;
2623
2624 result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) > 0) ? arg1 : arg2);
2625
2626 PG_RETURN_TEXT_P(result);
2627}

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

◆ text_le()

Datum text_le ( PG_FUNCTION_ARGS  )

Definition at line 1802 of file varlena.c.

1803{
1804 text *arg1 = PG_GETARG_TEXT_PP(0);
1805 text *arg2 = PG_GETARG_TEXT_PP(1);
1806 bool result;
1807
1808 result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) <= 0);
1809
1810 PG_FREE_IF_COPY(arg1, 0);
1811 PG_FREE_IF_COPY(arg2, 1);
1812
1813 PG_RETURN_BOOL(result);
1814}

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

Referenced by gbt_textle().

◆ text_left()

Datum text_left ( PG_FUNCTION_ARGS  )

Definition at line 5740 of file varlena.c.

5741{
5742 int n = PG_GETARG_INT32(1);
5743
5744 if (n < 0)
5745 {
5747 const char *p = VARDATA_ANY(str);
5748 int len = VARSIZE_ANY_EXHDR(str);
5749 int rlen;
5750
5751 n = pg_mbstrlen_with_len(p, len) + n;
5752 rlen = pg_mbcharcliplen(p, len, n);
5754 }
5755 else
5757}
int pg_mbstrlen_with_len(const char *mbstr, int limit)
Definition: mbutils.c:1057
int pg_mbcharcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1125
static text * text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
Definition: varlena.c:893

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

◆ text_length()

static int32 text_length ( Datum  str)
static

Definition at line 719 of file varlena.c.

720{
721 /* fastpath when max encoding length is one */
724 else
725 {
726 text *t = DatumGetTextPP(str);
727
730 }
731}
#define DatumGetTextPP(X)
Definition: fmgr.h:292

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

Referenced by textlen(), and textoverlay_no_len().

◆ text_lt()

Datum text_lt ( PG_FUNCTION_ARGS  )

Definition at line 1787 of file varlena.c.

1788{
1789 text *arg1 = PG_GETARG_TEXT_PP(0);
1790 text *arg2 = PG_GETARG_TEXT_PP(1);
1791 bool result;
1792
1793 result = (text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0);
1794
1795 PG_FREE_IF_COPY(arg1, 0);
1796 PG_FREE_IF_COPY(arg2, 1);
1797
1798 PG_RETURN_BOOL(result);
1799}

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

Referenced by gbt_textlt().

◆ text_name()

Datum text_name ( PG_FUNCTION_ARGS  )

Definition at line 3427 of file varlena.c.

3428{
3429 text *s = PG_GETARG_TEXT_PP(0);
3430 Name result;
3431 int len;
3432
3434
3435 /* Truncate oversize input */
3436 if (len >= NAMEDATALEN)
3438
3439 /* We use palloc0 here to ensure result is zero-padded */
3440 result = (Name) palloc0(NAMEDATALEN);
3441 memcpy(NameStr(*result), VARDATA_ANY(s), len);
3442
3443 PG_RETURN_NAME(result);
3444}
NameData * Name
Definition: c.h:715
#define PG_RETURN_NAME(x)
Definition: fmgr.h:363
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1083
void * palloc0(Size size)
Definition: mcxt.c:1347

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

◆ text_overlay()

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

Definition at line 1124 of file varlena.c.

1125{
1126 text *result;
1127 text *s1;
1128 text *s2;
1129 int sp_pl_sl;
1130
1131 /*
1132 * Check for possible integer-overflow cases. For negative sp, throw a
1133 * "substring length" error because that's what should be expected
1134 * according to the spec's definition of OVERLAY().
1135 */
1136 if (sp <= 0)
1137 ereport(ERROR,
1138 (errcode(ERRCODE_SUBSTRING_ERROR),
1139 errmsg("negative substring length not allowed")));
1140 if (pg_add_s32_overflow(sp, sl, &sp_pl_sl))
1141 ereport(ERROR,
1142 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1143 errmsg("integer out of range")));
1144
1145 s1 = text_substring(PointerGetDatum(t1), 1, sp - 1, false);
1146 s2 = text_substring(PointerGetDatum(t1), sp_pl_sl, -1, true);
1147 result = text_catenate(s1, t2);
1148 result = text_catenate(result, s2);
1149
1150 return result;
1151}
static text * text_catenate(text *t1, text *t2)
Definition: varlena.c:773

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

Referenced by textoverlay(), and textoverlay_no_len().

◆ text_pattern_ge()

Datum text_pattern_ge ( PG_FUNCTION_ARGS  )

Definition at line 2898 of file varlena.c.

2899{
2900 text *arg1 = PG_GETARG_TEXT_PP(0);
2901 text *arg2 = PG_GETARG_TEXT_PP(1);
2902 int result;
2903
2904 result = internal_text_pattern_compare(arg1, arg2);
2905
2906 PG_FREE_IF_COPY(arg1, 0);
2907 PG_FREE_IF_COPY(arg2, 1);
2908
2909 PG_RETURN_BOOL(result >= 0);
2910}

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

◆ text_pattern_gt()

Datum text_pattern_gt ( PG_FUNCTION_ARGS  )

Definition at line 2914 of file varlena.c.

2915{
2916 text *arg1 = PG_GETARG_TEXT_PP(0);
2917 text *arg2 = PG_GETARG_TEXT_PP(1);
2918 int result;
2919
2920 result = internal_text_pattern_compare(arg1, arg2);
2921
2922 PG_FREE_IF_COPY(arg1, 0);
2923 PG_FREE_IF_COPY(arg2, 1);
2924
2925 PG_RETURN_BOOL(result > 0);
2926}

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

◆ text_pattern_le()

Datum text_pattern_le ( PG_FUNCTION_ARGS  )

Definition at line 2882 of file varlena.c.

2883{
2884 text *arg1 = PG_GETARG_TEXT_PP(0);
2885 text *arg2 = PG_GETARG_TEXT_PP(1);
2886 int result;
2887
2888 result = internal_text_pattern_compare(arg1, arg2);
2889
2890 PG_FREE_IF_COPY(arg1, 0);
2891 PG_FREE_IF_COPY(arg2, 1);
2892
2893 PG_RETURN_BOOL(result <= 0);
2894}

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

◆ text_pattern_lt()

Datum text_pattern_lt ( PG_FUNCTION_ARGS  )

Definition at line 2866 of file varlena.c.

2867{
2868 text *arg1 = PG_GETARG_TEXT_PP(0);
2869 text *arg2 = PG_GETARG_TEXT_PP(1);
2870 int result;
2871
2872 result = internal_text_pattern_compare(arg1, arg2);
2873
2874 PG_FREE_IF_COPY(arg1, 0);
2875 PG_FREE_IF_COPY(arg2, 1);
2876
2877 PG_RETURN_BOOL(result < 0);
2878}

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

◆ text_position()

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

Definition at line 1184 of file varlena.c.

1185{
1187 int result;
1188
1190
1191 /* Empty needle always matches at position 1 */
1192 if (VARSIZE_ANY_EXHDR(t2) < 1)
1193 return 1;
1194
1195 /* Otherwise, can't match if haystack is shorter than needle */
1196 if (VARSIZE_ANY_EXHDR(t1) < VARSIZE_ANY_EXHDR(t2) &&
1197 pg_newlocale_from_collation(collid)->deterministic)
1198 return 0;
1199
1200 text_position_setup(t1, t2, collid, &state);
1201 /* don't need greedy mode here */
1202 state.greedy = false;
1203
1205 result = 0;
1206 else
1209 return result;
1210}
static int text_position_get_match_pos(TextPositionState *state)
Definition: varlena.c:1550

References check_collation_set(), collid, pg_newlocale_from_collation(), text_position_cleanup(), text_position_get_match_pos(), text_position_next(), text_position_setup(), and VARSIZE_ANY_EXHDR.

Referenced by textpos().

◆ text_position_cleanup()

static void text_position_cleanup ( TextPositionState state)
static

Definition at line 1574 of file varlena.c.

1575{
1576 /* no cleanup needed */
1577}

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

◆ text_position_get_match_pos()

static int text_position_get_match_pos ( TextPositionState state)
static

Definition at line 1550 of file varlena.c.

1551{
1552 /* Convert the byte position to char position. */
1553 state->refpos += pg_mbstrlen_with_len(state->refpoint,
1554 state->last_match - state->refpoint);
1555 state->refpoint = state->last_match;
1556 return state->refpos + 1;
1557}

References pg_mbstrlen_with_len().

Referenced by text_position().

◆ text_position_get_match_ptr()

static char * text_position_get_match_ptr ( TextPositionState state)
static

Definition at line 1539 of file varlena.c.

1540{
1541 return state->last_match;
1542}

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

◆ text_position_next()

static bool text_position_next ( TextPositionState state)
static

Definition at line 1351 of file varlena.c.

1352{
1353 int needle_len = state->len2;
1354 char *start_ptr;
1355 char *matchptr;
1356
1357 if (needle_len <= 0)
1358 return false; /* result for empty pattern */
1359
1360 /* Start from the point right after the previous match. */
1361 if (state->last_match)
1362 start_ptr = state->last_match + state->last_match_len;
1363 else
1364 start_ptr = state->str1;
1365
1366retry:
1367 matchptr = text_position_next_internal(start_ptr, state);
1368
1369 if (!matchptr)
1370 return false;
1371
1372 /*
1373 * Found a match for the byte sequence. If this is a multibyte encoding,
1374 * where one character's byte sequence can appear inside a longer
1375 * multi-byte character, we need to verify that the match was at a
1376 * character boundary, not in the middle of a multi-byte character.
1377 */
1378 if (state->is_multibyte_char_in_char && state->locale->deterministic)
1379 {
1380 /* Walk one character at a time, until we reach the match. */
1381
1382 /* the search should never move backwards. */
1383 Assert(state->refpoint <= matchptr);
1384
1385 while (state->refpoint < matchptr)
1386 {
1387 /* step to next character. */
1388 state->refpoint += pg_mblen(state->refpoint);
1389 state->refpos++;
1390
1391 /*
1392 * If we stepped over the match's start position, then it was a
1393 * false positive, where the byte sequence appeared in the middle
1394 * of a multi-byte character. Skip it, and continue the search at
1395 * the next character boundary.
1396 */
1397 if (state->refpoint > matchptr)
1398 {
1399 start_ptr = state->refpoint;
1400 goto retry;
1401 }
1402 }
1403 }
1404
1405 state->last_match = matchptr;
1406 state->last_match_len = state->last_match_len_tmp;
1407 return true;
1408}
static char * text_position_next_internal(char *start_ptr, TextPositionState *state)
Definition: varlena.c:1416

References Assert(), pg_mblen(), and text_position_next_internal().

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

◆ text_position_next_internal()

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

Definition at line 1416 of file varlena.c.

1417{
1418 int haystack_len = state->len1;
1419 int needle_len = state->len2;
1420 int skiptablemask = state->skiptablemask;
1421 const char *haystack = state->str1;
1422 const char *needle = state->str2;
1423 const char *haystack_end = &haystack[haystack_len];
1424 const char *hptr;
1425
1426 Assert(start_ptr >= haystack && start_ptr <= haystack_end);
1427
1428 state->last_match_len_tmp = needle_len;
1429
1430 if (!state->locale->deterministic)
1431 {
1432 /*
1433 * With a nondeterministic collation, we have to use an unoptimized
1434 * route. We walk through the haystack and see if at each position
1435 * there is a substring of the remaining string that is equal to the
1436 * needle under the given collation.
1437 *
1438 * Note, the found substring could have a different length than the
1439 * needle, including being empty. Callers that want to skip over the
1440 * found string need to read the length of the found substring from
1441 * last_match_len rather than just using the length of their needle.
1442 *
1443 * Most callers will require "greedy" semantics, meaning that we need
1444 * to find the longest such substring, not the shortest. For callers
1445 * that don't need greedy semantics, we can finish on the first match.
1446 */
1447 const char *result_hptr = NULL;
1448
1449 hptr = start_ptr;
1450 while (hptr < haystack_end)
1451 {
1452 /*
1453 * First check the common case that there is a match in the
1454 * haystack of exactly the length of the needle.
1455 */
1456 if (!state->greedy &&
1457 haystack_end - hptr >= needle_len &&
1458 pg_strncoll(hptr, needle_len, needle, needle_len, state->locale) == 0)
1459 return (char *) hptr;
1460
1461 /*
1462 * Else check if any of the possible substrings starting at hptr
1463 * are equal to the needle.
1464 */
1465 for (const char *test_end = hptr; test_end < haystack_end; test_end += pg_mblen(test_end))
1466 {
1467 if (pg_strncoll(hptr, (test_end - hptr), needle, needle_len, state->locale) == 0)
1468 {
1469 state->last_match_len_tmp = (test_end - hptr);
1470 result_hptr = hptr;
1471 if (!state->greedy)
1472 break;
1473 }
1474 }
1475 if (result_hptr)
1476 break;
1477
1478 hptr += pg_mblen(hptr);
1479 }
1480
1481 return (char *) result_hptr;
1482 }
1483 else if (needle_len == 1)
1484 {
1485 /* No point in using B-M-H for a one-character needle */
1486 char nchar = *needle;
1487
1488 hptr = start_ptr;
1489 while (hptr < haystack_end)
1490 {
1491 if (*hptr == nchar)
1492 return (char *) hptr;
1493 hptr++;
1494 }
1495 }
1496 else
1497 {
1498 const char *needle_last = &needle[needle_len - 1];
1499
1500 /* Start at startpos plus the length of the needle */
1501 hptr = start_ptr + needle_len - 1;
1502 while (hptr < haystack_end)
1503 {
1504 /* Match the needle scanning *backward* */
1505 const char *nptr;
1506 const char *p;
1507
1508 nptr = needle_last;
1509 p = hptr;
1510 while (*nptr == *p)
1511 {
1512 /* Matched it all? If so, return 1-based position */
1513 if (nptr == needle)
1514 return (char *) p;
1515 nptr--, p--;
1516 }
1517
1518 /*
1519 * No match, so use the haystack char at hptr to decide how far to
1520 * advance. If the needle had any occurrence of that character
1521 * (or more precisely, one sharing the same skiptable entry)
1522 * before its last character, then we advance far enough to align
1523 * the last such needle character with that haystack position.
1524 * Otherwise we can advance by the whole needle length.
1525 */
1526 hptr += state->skiptable[(unsigned char) *hptr & skiptablemask];
1527 }
1528 }
1529
1530 return 0; /* not found */
1531}
int pg_strncoll(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, pg_locale_t locale)
Definition: pg_locale.c:1356

References Assert(), pg_mblen(), and pg_strncoll().

Referenced by text_position_next().

◆ text_position_reset()

static void text_position_reset ( TextPositionState state)
static

Definition at line 1566 of file varlena.c.

1567{
1568 state->last_match = NULL;
1569 state->refpoint = state->str1;
1570 state->refpos = 0;
1571}

Referenced by split_part().

◆ text_position_setup()

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

Definition at line 1230 of file varlena.c.

1231{
1232 int len1 = VARSIZE_ANY_EXHDR(t1);
1233 int len2 = VARSIZE_ANY_EXHDR(t2);
1234
1236
1238
1239 /*
1240 * Most callers need greedy mode, but some might want to unset this to
1241 * optimize.
1242 */
1243 state->greedy = true;
1244
1245 Assert(len2 > 0);
1246
1247 /*
1248 * Even with a multi-byte encoding, we perform the search using the raw
1249 * byte sequence, ignoring multibyte issues. For UTF-8, that works fine,
1250 * because in UTF-8 the byte sequence of one character cannot contain
1251 * another character. For other multi-byte encodings, we do the search
1252 * initially as a simple byte search, ignoring multibyte issues, but
1253 * verify afterwards that the match we found is at a character boundary,
1254 * and continue the search if it was a false match.
1255 */
1257 state->is_multibyte_char_in_char = false;
1258 else if (GetDatabaseEncoding() == PG_UTF8)
1259 state->is_multibyte_char_in_char = false;
1260 else
1261 state->is_multibyte_char_in_char = true;
1262
1263 state->str1 = VARDATA_ANY(t1);
1264 state->str2 = VARDATA_ANY(t2);
1265 state->len1 = len1;
1266 state->len2 = len2;
1267 state->last_match = NULL;
1268 state->refpoint = state->str1;
1269 state->refpos = 0;
1270
1271 /*
1272 * Prepare the skip table for Boyer-Moore-Horspool searching. In these
1273 * notes we use the terminology that the "haystack" is the string to be
1274 * searched (t1) and the "needle" is the pattern being sought (t2).
1275 *
1276 * If the needle is empty or bigger than the haystack then there is no
1277 * point in wasting cycles initializing the table. We also choose not to
1278 * use B-M-H for needles of length 1, since the skip table can't possibly
1279 * save anything in that case.
1280 *
1281 * (With nondeterministic collations, the search is already
1282 * multibyte-aware, so we don't need this.)
1283 */
1284 if (len1 >= len2 && len2 > 1 && state->locale->deterministic)
1285 {
1286 int searchlength = len1 - len2;
1287 int skiptablemask;
1288 int last;
1289 int i;
1290 const char *str2 = state->str2;
1291
1292 /*
1293 * First we must determine how much of the skip table to use. The
1294 * declaration of TextPositionState allows up to 256 elements, but for
1295 * short search problems we don't really want to have to initialize so
1296 * many elements --- it would take too long in comparison to the
1297 * actual search time. So we choose a useful skip table size based on
1298 * the haystack length minus the needle length. The closer the needle
1299 * length is to the haystack length the less useful skipping becomes.
1300 *
1301 * Note: since we use bit-masking to select table elements, the skip
1302 * table size MUST be a power of 2, and so the mask must be 2^N-1.
1303 */
1304 if (searchlength < 16)
1305 skiptablemask = 3;
1306 else if (searchlength < 64)
1307 skiptablemask = 7;
1308 else if (searchlength < 128)
1309 skiptablemask = 15;
1310 else if (searchlength < 512)
1311 skiptablemask = 31;
1312 else if (searchlength < 2048)
1313 skiptablemask = 63;
1314 else if (searchlength < 4096)
1315 skiptablemask = 127;
1316 else
1317 skiptablemask = 255;
1318 state->skiptablemask = skiptablemask;
1319
1320 /*
1321 * Initialize the skip table. We set all elements to the needle
1322 * length, since this is the correct skip distance for any character
1323 * not found in the needle.
1324 */
1325 for (i = 0; i <= skiptablemask; i++)
1326 state->skiptable[i] = len2;
1327
1328 /*
1329 * Now examine the needle. For each character except the last one,
1330 * set the corresponding table element to the appropriate skip
1331 * distance. Note that when two characters share the same skip table
1332 * entry, the one later in the needle must determine the skip
1333 * distance.
1334 */
1335 last = len2 - 1;
1336
1337 for (i = 0; i < last; i++)
1338 state->skiptable[(unsigned char) str2[i] & skiptablemask] = last - i;
1339 }
1340}
for(;;)
int GetDatabaseEncoding(void)
Definition: mbutils.c:1261
@ PG_UTF8
Definition: pg_wchar.h:232

References Assert(), check_collation_set(), collid, for(), GetDatabaseEncoding(), i, pg_database_encoding_max_length(), pg_newlocale_from_collation(), PG_UTF8, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

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

◆ text_reverse()

Datum text_reverse ( PG_FUNCTION_ARGS  )

Definition at line 5785 of file varlena.c.

5786{
5788 const char *p = VARDATA_ANY(str);
5789 int len = VARSIZE_ANY_EXHDR(str);
5790 const char *endp = p + len;
5791 text *result;
5792 char *dst;
5793
5794 result = palloc(len + VARHDRSZ);
5795 dst = (char *) VARDATA(result) + len;
5796 SET_VARSIZE(result, len + VARHDRSZ);
5797
5799 {
5800 /* multibyte version */
5801 while (p < endp)
5802 {
5803 int sz;
5804
5805 sz = pg_mblen(p);
5806 dst -= sz;
5807 memcpy(dst, p, sz);
5808 p += sz;
5809 }
5810 }
5811 else
5812 {
5813 /* single byte version */
5814 while (p < endp)
5815 *(--dst) = *p++;
5816 }
5817
5818 PG_RETURN_TEXT_P(result);
5819}

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

◆ text_right()

Datum text_right ( PG_FUNCTION_ARGS  )

Definition at line 5764 of file varlena.c.

5765{
5767 const char *p = VARDATA_ANY(str);
5768 int len = VARSIZE_ANY_EXHDR(str);
5769 int n = PG_GETARG_INT32(1);
5770 int off;
5771
5772 if (n < 0)
5773 n = -n;
5774 else
5775 n = pg_mbstrlen_with_len(p, len) - n;
5776 off = pg_mbcharcliplen(p, len, n);
5777
5779}

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

◆ text_smaller()

Datum text_smaller ( PG_FUNCTION_ARGS  )

Definition at line 2630 of file varlena.c.

2631{
2632 text *arg1 = PG_GETARG_TEXT_PP(0);
2633 text *arg2 = PG_GETARG_TEXT_PP(1);
2634 text *result;
2635
2636 result = ((text_cmp(arg1, arg2, PG_GET_COLLATION()) < 0) ? arg1 : arg2);
2637
2638 PG_RETURN_TEXT_P(result);
2639}

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

◆ text_starts_with()

Datum text_starts_with ( PG_FUNCTION_ARGS  )

Definition at line 1847 of file varlena.c.

1848{
1849 Datum arg1 = PG_GETARG_DATUM(0);
1850 Datum arg2 = PG_GETARG_DATUM(1);
1852 pg_locale_t mylocale;
1853 bool result;
1854 Size len1,
1855 len2;
1856
1858
1860
1861 if (!mylocale->deterministic)
1862 ereport(ERROR,
1863 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1864 errmsg("nondeterministic collations are not supported for substring searches")));
1865
1866 len1 = toast_raw_datum_size(arg1);
1867 len2 = toast_raw_datum_size(arg2);
1868 if (len2 > len1)
1869 result = false;
1870 else
1871 {
1872 text *targ1 = text_substring(arg1, 1, len2, false);
1873 text *targ2 = DatumGetTextPP(arg2);
1874
1875 result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2),
1876 VARSIZE_ANY_EXHDR(targ2)) == 0);
1877
1878 PG_FREE_IF_COPY(targ1, 0);
1879 PG_FREE_IF_COPY(targ2, 1);
1880 }
1881
1882 PG_RETURN_BOOL(result);
1883}
bool deterministic
Definition: pg_locale.h:99

References check_collation_set(), collid, DatumGetTextPP, pg_locale_struct::deterministic, ereport, errcode(), errmsg(), ERROR, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_DATUM, pg_newlocale_from_collation(), PG_RETURN_BOOL, text_substring(), toast_raw_datum_size(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by spg_text_leaf_consistent(), and t_starts_with().

◆ text_substr()

◆ text_substr_no_len()

Datum text_substr_no_len ( PG_FUNCTION_ARGS  )

Definition at line 874 of file varlena.c.

875{
878 -1, true));
879}

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

◆ text_substring()

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

Definition at line 893 of file varlena.c.

894{
896 int32 S = start; /* start position */
897 int32 S1; /* adjusted start position */
898 int32 L1; /* adjusted substring length */
899 int32 E; /* end position */
900
901 /*
902 * SQL99 says S can be zero or negative (which we don't document), but we
903 * still must fetch from the start of the string.
904 * https://www.postgresql.org/message-id/170905442373.643.11536838320909376197%40wrigleys.postgresql.org
905 */
906 S1 = Max(S, 1);
907
908 /* life is easy if the encoding max length is 1 */
909 if (eml == 1)
910 {
911 if (length_not_specified) /* special case - get length to end of
912 * string */
913 L1 = -1;
914 else if (length < 0)
915 {
916 /* SQL99 says to throw an error for E < S, i.e., negative length */
918 (errcode(ERRCODE_SUBSTRING_ERROR),
919 errmsg("negative substring length not allowed")));
920 L1 = -1; /* silence stupider compilers */
921 }
922 else if (pg_add_s32_overflow(S, length, &E))
923 {
924 /*
925 * L could be large enough for S + L to overflow, in which case
926 * the substring must run to end of string.
927 */
928 L1 = -1;
929 }
930 else
931 {
932 /*
933 * A zero or negative value for the end position can happen if the
934 * start was negative or one. SQL99 says to return a zero-length
935 * string.
936 */
937 if (E < 1)
938 return cstring_to_text("");
939
940 L1 = E - S1;
941 }
942
943 /*
944 * If the start position is past the end of the string, SQL99 says to
945 * return a zero-length string -- DatumGetTextPSlice() will do that
946 * for us. We need only convert S1 to zero-based starting position.
947 */
948 return DatumGetTextPSlice(str, S1 - 1, L1);
949 }
950 else if (eml > 1)
951 {
952 /*
953 * When encoding max length is > 1, we can't get LC without
954 * detoasting, so we'll grab a conservatively large slice now and go
955 * back later to do the right thing
956 */
957 int32 slice_start;
958 int32 slice_size;
959 int32 slice_strlen;
960 text *slice;
961 int32 E1;
962 int32 i;
963 char *p;
964 char *s;
965 text *ret;
966
967 /*
968 * We need to start at position zero because there is no way to know
969 * in advance which byte offset corresponds to the supplied start
970 * position.
971 */
972 slice_start = 0;
973
974 if (length_not_specified) /* special case - get length to end of
975 * string */
976 slice_size = L1 = -1;
977 else if (length < 0)
978 {
979 /* SQL99 says to throw an error for E < S, i.e., negative length */
981 (errcode(ERRCODE_SUBSTRING_ERROR),
982 errmsg("negative substring length not allowed")));
983 slice_size = L1 = -1; /* silence stupider compilers */
984 }
985 else if (pg_add_s32_overflow(S, length, &E))
986 {
987 /*
988 * L could be large enough for S + L to overflow, in which case
989 * the substring must run to end of string.
990 */
991 slice_size = L1 = -1;
992 }
993 else
994 {
995 /*
996 * A zero or negative value for the end position can happen if the
997 * start was negative or one. SQL99 says to return a zero-length
998 * string.
999 */
1000 if (E < 1)
1001 return cstring_to_text("");
1002
1003 /*
1004 * if E is past the end of the string, the tuple toaster will
1005 * truncate the length for us
1006 */
1007 L1 = E - S1;
1008
1009 /*
1010 * Total slice size in bytes can't be any longer than the start
1011 * position plus substring length times the encoding max length.
1012 * If that overflows, we can just use -1.
1013 */
1014 if (pg_mul_s32_overflow(E, eml, &slice_size))
1015 slice_size = -1;
1016 }
1017
1018 /*
1019 * If we're working with an untoasted source, no need to do an extra
1020 * copying step.
1021 */
1024 slice = DatumGetTextPSlice(str, slice_start, slice_size);
1025 else
1026 slice = (text *) DatumGetPointer(str);
1027
1028 /* see if we got back an empty string */
1029 if (VARSIZE_ANY_EXHDR(slice) == 0)
1030 {
1031 if (slice != (text *) DatumGetPointer(str))
1032 pfree(slice);
1033 return cstring_to_text("");
1034 }
1035
1036 /* Now we can get the actual length of the slice in MB characters */
1037 slice_strlen = pg_mbstrlen_with_len(VARDATA_ANY(slice),
1038 VARSIZE_ANY_EXHDR(slice));
1039
1040 /*
1041 * Check that the start position wasn't > slice_strlen. If so, SQL99
1042 * says to return a zero-length string.
1043 */
1044 if (S1 > slice_strlen)
1045 {
1046 if (slice != (text *) DatumGetPointer(str))
1047 pfree(slice);
1048 return cstring_to_text("");
1049 }
1050
1051 /*
1052 * Adjust L1 and E1 now that we know the slice string length. Again
1053 * remember that S1 is one based, and slice_start is zero based.
1054 */
1055 if (L1 > -1)
1056 E1 = Min(S1 + L1, slice_start + 1 + slice_strlen);
1057 else
1058 E1 = slice_start + 1 + slice_strlen;
1059
1060 /*
1061 * Find the start position in the slice; remember S1 is not zero based
1062 */
1063 p = VARDATA_ANY(slice);
1064 for (i = 0; i < S1 - 1; i++)
1065 p += pg_mblen(p);
1066
1067 /* hang onto a pointer to our start position */
1068 s = p;
1069
1070 /*
1071 * Count the actual bytes used by the substring of the requested
1072 * length.
1073 */
1074 for (i = S1; i < E1; i++)
1075 p += pg_mblen(p);
1076
1077 ret = (text *) palloc(VARHDRSZ + (p - s));
1078 SET_VARSIZE(ret, VARHDRSZ + (p - s));
1079 memcpy(VARDATA(ret), s, (p - s));
1080
1081 if (slice != (text *) DatumGetPointer(str))
1082 pfree(slice);
1083
1084 return ret;
1085 }
1086 else
1087 elog(ERROR, "invalid backend encoding: encoding max length < 1");
1088
1089 /* not reached: suppress compiler warning */
1090 return NULL;
1091}
#define DatumGetTextPSlice(X, m, n)
Definition: fmgr.h:304
return str start
#define VARATT_IS_COMPRESSED(PTR)
Definition: varatt.h:288
#define VARATT_IS_EXTERNAL(PTR)
Definition: varatt.h:289

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

Referenced by text_left(), text_overlay(), text_starts_with(), text_substr(), and text_substr_no_len().

◆ text_to_array()

Datum text_to_array ( PG_FUNCTION_ARGS  )

Definition at line 4716 of file varlena.c.

4717{
4718 SplitTextOutputData tstate;
4719
4720 /* For array output, tstate should start as all zeroes */
4721 memset(&tstate, 0, sizeof(tstate));
4722
4723 if (!split_text(fcinfo, &tstate))
4725
4726 if (tstate.astate == NULL)
4728
4731}
#define PG_RETURN_ARRAYTYPE_P(x)
Definition: array.h:265
ArrayType * construct_empty_array(Oid elmtype)
Definition: arrayfuncs.c:3580
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
Definition: arrayfuncs.c:5420
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
static bool split_text(FunctionCallInfo fcinfo, SplitTextOutputData *tstate)
Definition: varlena.c:4793

References SplitTextOutputData::astate, construct_empty_array(), CurrentMemoryContext, makeArrayResult(), PG_RETURN_ARRAYTYPE_P, PG_RETURN_DATUM, PG_RETURN_NULL, and split_text().

Referenced by text_to_array_null().

◆ text_to_array_null()

Datum text_to_array_null ( PG_FUNCTION_ARGS  )

Definition at line 4742 of file varlena.c.

4743{
4744 return text_to_array(fcinfo);
4745}
Datum text_to_array(PG_FUNCTION_ARGS)
Definition: varlena.c:4716

References text_to_array().

◆ text_to_cstring()

char * text_to_cstring ( const text t)

Definition at line 225 of file varlena.c.

226{
227 /* must cast away the const, unfortunately */
228 text *tunpacked = pg_detoast_datum_packed(unconstify(text *, t));
229 int len = VARSIZE_ANY_EXHDR(tunpacked);
230 char *result;
231
232 result = (char *) palloc(len + 1);
233 memcpy(result, VARDATA_ANY(tunpacked), len);
234 result[len] = '\0';
235
236 if (tunpacked != t)
237 pfree(tunpacked);
238
239 return result;
240}
#define unconstify(underlying_type, expr)
Definition: c.h:1216
struct varlena * pg_detoast_datum_packed(struct varlena *datum)
Definition: fmgr.c:1864

References len, palloc(), pfree(), pg_detoast_datum_packed(), unconstify, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by array_to_text(), array_to_text_null(), binary_upgrade_add_sub_rel_state(), binary_upgrade_create_empty_extension(), binary_upgrade_replorigin_advance(), binary_upgrade_set_missing_value(), connectby_text(), connectby_text_serial(), convert_and_check_filename(), convert_any_priv_string(), convert_column_name(), convert_database_name(), convert_foreign_data_wrapper_name(), convert_function_name(), convert_language_name(), convert_schema_name(), convert_server_name(), convert_tablespace_name(), convert_type_name(), crosstab(), crosstab_hash(), cursor_to_xml(), cursor_to_xmlschema(), daitch_mokotoff(), database_to_xml(), database_to_xml_and_xmlschema(), database_to_xmlschema(), datetime_to_char_body(), dblink_cancel_query(), dblink_close(), dblink_connect(), dblink_disconnect(), dblink_error_message(), dblink_exec(), dblink_fetch(), dblink_get_notify(), dblink_is_busy(), dblink_open(), dblink_record_internal(), dblink_send_query(), deserialize_deflist(), difference(), dmetaphone(), dmetaphone_alt(), do_to_timestamp(), ExecAlterExtensionStmt(), execute_extension_script(), executeDateTimeMethod(), get_raw_page_fork(), get_raw_page_fork_1_9(), has_param_priv_byname(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_name(), injection_points_attach(), injection_points_cached(), injection_points_detach(), injection_points_load(), injection_points_run(), injection_points_stats_numcalls(), injection_points_wakeup(), json_object_field(), json_object_field_text(), jsonb_set_lax(), JsonItemFromDatum(), ltree_addtext(), ltree_textadd(), NUM_cache(), parse_datetime(), parse_ident(), pg_backup_start(), pg_create_restore_point(), pg_crypt(), pg_current_logfile(), pg_get_expr_worker(), pg_get_logical_snapshot_info(), pg_get_logical_snapshot_meta(), pg_get_serial_sequence(), pg_index_column_has_property(), pg_index_has_property(), pg_indexam_has_property(), pg_input_is_valid_common(), pg_logical_emit_message_bytea(), pg_ls_replslotdir(), pg_notify(), pg_prewarm(), pg_relation_size(), pg_replication_origin_advance(), pg_replication_origin_create(), pg_replication_origin_drop(), pg_replication_origin_oid(), pg_replication_origin_progress(), pg_replication_origin_session_setup(), pg_size_bytes(), pg_split_walfile_name(), pg_stat_get_progress_info(), pg_stat_get_replication_slot(), pg_stat_have_stats(), pg_stat_reset_replication_slot(), pg_stat_reset_shared(), pg_stat_reset_slru(), pgxml_texttoxmlchar(), phraseto_tsquery_byid(), plainto_tsquery_byid(), postgres_fdw_disconnect(), query_to_xml(), query_to_xml_and_xmlschema(), query_to_xmlschema(), quote_ident(), quote_ident_cstr(), range_constructor3(), regress_setenv(), replorigin_by_oid(), schema_to_xml(), schema_to_xml_and_xmlschema(), schema_to_xmlschema(), sepgsql_mcstrans_in(), sepgsql_mcstrans_out(), soundex(), table_to_xml(), table_to_xml_and_xmlschema(), table_to_xmlschema(), test_canonicalize_path(), test_predtest(), test_slru_page_write(), text2ltree(), text_concat_ws(), textToQualifiedNameList(), to_date(), to_regclass(), to_regcollation(), to_regnamespace(), to_regoper(), to_regoperator(), to_regproc(), to_regprocedure(), to_regrole(), to_regtype(), to_regtypemod(), to_tsquery_byid(), ts_stat_sql(), tsquery_rewrite_query(), tuple_data_split(), unicode_is_normalized(), unicode_normalize_func(), verify_heapam(), websearch_to_tsquery_byid(), X509_NAME_field_to_text(), xml_out_internal(), xmlconcat(), xmlpi(), xmlroot(), and xpath_table().

◆ text_to_cstring_buffer()

void text_to_cstring_buffer ( const text src,
char *  dst,
size_t  dst_len 
)

Definition at line 256 of file varlena.c.

257{
258 /* must cast away the const, unfortunately */
259 text *srcunpacked = pg_detoast_datum_packed(unconstify(text *, src));
260 size_t src_len = VARSIZE_ANY_EXHDR(srcunpacked);
261
262 if (dst_len > 0)
263 {
264 dst_len--;
265 if (dst_len >= src_len)
266 dst_len = src_len;
267 else /* ensure truncation is encoding-safe */
268 dst_len = pg_mbcliplen(VARDATA_ANY(srcunpacked), src_len, dst_len);
269 memcpy(dst, VARDATA_ANY(srcunpacked), dst_len);
270 dst[dst_len] = '\0';
271 }
272
273 if (srcunpacked != src)
274 pfree(srcunpacked);
275}

References pfree(), pg_detoast_datum_packed(), pg_mbcliplen(), unconstify, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by be_lo_export(), lo_import_internal(), lookup_timezone(), parse_sane_timezone(), pg_gen_salt(), pg_gen_salt_rounds(), timestamp_zone(), timestamptz_zone(), and timetz_zone().

◆ text_to_table()

Datum text_to_table ( PG_FUNCTION_ARGS  )

Definition at line 4753 of file varlena.c.

4754{
4755 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
4756 SplitTextOutputData tstate;
4757
4758 tstate.astate = NULL;
4760 tstate.tupstore = rsi->setResult;
4761 tstate.tupdesc = rsi->setDesc;
4762
4763 (void) split_text(fcinfo, &tstate);
4764
4765 return (Datum) 0;
4766}
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition: funcapi.h:296
TupleDesc setDesc
Definition: execnodes.h:359
Tuplestorestate * setResult
Definition: execnodes.h:358

References SplitTextOutputData::astate, InitMaterializedSRF(), MAT_SRF_USE_EXPECTED_DESC, ReturnSetInfo::setDesc, ReturnSetInfo::setResult, and split_text().

Referenced by text_to_table_null().

◆ text_to_table_null()

Datum text_to_table_null ( PG_FUNCTION_ARGS  )

Definition at line 4777 of file varlena.c.

4778{
4779 return text_to_table(fcinfo);
4780}
Datum text_to_table(PG_FUNCTION_ARGS)
Definition: varlena.c:4753

References text_to_table().

◆ textcat()

Datum textcat ( PG_FUNCTION_ARGS  )

Definition at line 758 of file varlena.c.

759{
760 text *t1 = PG_GETARG_TEXT_PP(0);
761 text *t2 = PG_GETARG_TEXT_PP(1);
762
764}

References PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, and text_catenate().

◆ texteq()

Datum texteq ( PG_FUNCTION_ARGS  )

Definition at line 1683 of file varlena.c.

1684{
1686 pg_locale_t mylocale = 0;
1687 bool result;
1688
1690
1692
1693 if (mylocale->deterministic)
1694 {
1695 Datum arg1 = PG_GETARG_DATUM(0);
1696 Datum arg2 = PG_GETARG_DATUM(1);
1697 Size len1,
1698 len2;
1699
1700 /*
1701 * Since we only care about equality or not-equality, we can avoid all
1702 * the expense of strcoll() here, and just do bitwise comparison. In
1703 * fact, we don't even have to do a bitwise comparison if we can show
1704 * the lengths of the strings are unequal; which might save us from
1705 * having to detoast one or both values.
1706 */
1707 len1 = toast_raw_datum_size(arg1);
1708 len2 = toast_raw_datum_size(arg2);
1709 if (len1 != len2)
1710 result = false;
1711 else
1712 {
1713 text *targ1 = DatumGetTextPP(arg1);
1714 text *targ2 = DatumGetTextPP(arg2);
1715
1716 result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2),
1717 len1 - VARHDRSZ) == 0);
1718
1719 PG_FREE_IF_COPY(targ1, 0);
1720 PG_FREE_IF_COPY(targ2, 1);
1721 }
1722 }
1723 else
1724 {
1725 text *arg1 = PG_GETARG_TEXT_PP(0);
1726 text *arg2 = PG_GETARG_TEXT_PP(1);
1727
1728 result = (text_cmp(arg1, arg2, collid) == 0);
1729
1730 PG_FREE_IF_COPY(arg1, 0);
1731 PG_FREE_IF_COPY(arg2, 1);
1732 }
1733
1734 PG_RETURN_BOOL(result);
1735}

References check_collation_set(), collid, DatumGetTextPP, pg_locale_struct::deterministic, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_DATUM, PG_GETARG_TEXT_PP, pg_newlocale_from_collation(), PG_RETURN_BOOL, text_cmp(), toast_raw_datum_size(), VARDATA_ANY, and VARHDRSZ.

Referenced by gbt_texteq(), text_isequal(), and texteqfast().

◆ texteqname()

Datum texteqname ( PG_FUNCTION_ARGS  )

Definition at line 2672 of file varlena.c.

2673{
2674 text *arg1 = PG_GETARG_TEXT_PP(0);
2675 Name arg2 = PG_GETARG_NAME(1);
2676 size_t len1 = VARSIZE_ANY_EXHDR(arg1);
2677 size_t len2 = strlen(NameStr(*arg2));
2679 bool result;
2680
2682
2683 if (collid == C_COLLATION_OID)
2684 result = (len1 == len2 &&
2685 memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
2686 else
2687 result = (varstr_cmp(VARDATA_ANY(arg1), len1,
2688 NameStr(*arg2), len2,
2689 collid) == 0);
2690
2691 PG_FREE_IF_COPY(arg1, 0);
2692
2693 PG_RETURN_BOOL(result);
2694}

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

◆ textgename()

Datum textgename ( PG_FUNCTION_ARGS  )

Definition at line 2827 of file varlena.c.

2828{
2830}
Datum bttextnamecmp(PG_FUNCTION_ARGS)
Definition: varlena.c:2763

References bttextnamecmp(), CmpCall, and PG_RETURN_BOOL.

◆ textgtname()

Datum textgtname ( PG_FUNCTION_ARGS  )

Definition at line 2821 of file varlena.c.

2822{
2824}

References bttextnamecmp(), CmpCall, and PG_RETURN_BOOL.

◆ textin()

Datum textin ( PG_FUNCTION_ARGS  )

Definition at line 587 of file varlena.c.

588{
589 char *inputText = PG_GETARG_CSTRING(0);
590
592}

References cstring_to_text(), PG_GETARG_CSTRING, and PG_RETURN_TEXT_P.

Referenced by ExecEvalJsonExprPath().

◆ textlen()

Datum textlen ( PG_FUNCTION_ARGS  )

Definition at line 701 of file varlena.c.

702{
704
705 /* try to avoid decompressing argument */
707}
static int32 text_length(Datum str)
Definition: varlena.c:719

References PG_GETARG_DATUM, PG_RETURN_INT32, str, and text_length().

◆ textlename()

Datum textlename ( PG_FUNCTION_ARGS  )

Definition at line 2815 of file varlena.c.

2816{
2818}

References bttextnamecmp(), CmpCall, and PG_RETURN_BOOL.

◆ textltname()

Datum textltname ( PG_FUNCTION_ARGS  )

Definition at line 2809 of file varlena.c.

2810{
2812}

References bttextnamecmp(), CmpCall, and PG_RETURN_BOOL.

◆ textne()

Datum textne ( PG_FUNCTION_ARGS  )

Definition at line 1738 of file varlena.c.

1739{
1741 pg_locale_t mylocale;
1742 bool result;
1743
1745
1747
1748 if (mylocale->deterministic)
1749 {
1750 Datum arg1 = PG_GETARG_DATUM(0);
1751 Datum arg2 = PG_GETARG_DATUM(1);
1752 Size len1,
1753 len2;
1754
1755 /* See comment in texteq() */
1756 len1 = toast_raw_datum_size(arg1);
1757 len2 = toast_raw_datum_size(arg2);
1758 if (len1 != len2)
1759 result = true;
1760 else
1761 {
1762 text *targ1 = DatumGetTextPP(arg1);
1763 text *targ2 = DatumGetTextPP(arg2);
1764
1765 result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2),
1766 len1 - VARHDRSZ) != 0);
1767
1768 PG_FREE_IF_COPY(targ1, 0);
1769 PG_FREE_IF_COPY(targ2, 1);
1770 }
1771 }
1772 else
1773 {
1774 text *arg1 = PG_GETARG_TEXT_PP(0);
1775 text *arg2 = PG_GETARG_TEXT_PP(1);
1776
1777 result = (text_cmp(arg1, arg2, collid) != 0);
1778
1779 PG_FREE_IF_COPY(arg1, 0);
1780 PG_FREE_IF_COPY(arg2, 1);
1781 }
1782
1783 PG_RETURN_BOOL(result);
1784}

References check_collation_set(), collid, DatumGetTextPP, pg_locale_struct::deterministic, PG_FREE_IF_COPY, PG_GET_COLLATION, PG_GETARG_DATUM, PG_GETARG_TEXT_PP, pg_newlocale_from_collation(), PG_RETURN_BOOL, text_cmp(), toast_raw_datum_size(), VARDATA_ANY, and VARHDRSZ.

◆ textnename()

Datum textnename ( PG_FUNCTION_ARGS  )

Definition at line 2722 of file varlena.c.

2723{
2724 text *arg1 = PG_GETARG_TEXT_PP(0);
2725 Name arg2 = PG_GETARG_NAME(1);
2726 size_t len1 = VARSIZE_ANY_EXHDR(arg1);
2727 size_t len2 = strlen(NameStr(*arg2));
2729 bool result;
2730
2732
2733 if (collid == C_COLLATION_OID)
2734 result = !(len1 == len2 &&
2735 memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0);
2736 else
2737 result = !(varstr_cmp(VARDATA_ANY(arg1), len1,
2738 NameStr(*arg2), len2,
2739 collid) == 0);
2740
2741 PG_FREE_IF_COPY(arg1, 0);
2742
2743 PG_RETURN_BOOL(result);
2744}

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

◆ textoctetlen()

Datum textoctetlen ( PG_FUNCTION_ARGS  )

Definition at line 739 of file varlena.c.

740{
742
743 /* We need not detoast the input at all */
745}

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

◆ textout()

Datum textout ( PG_FUNCTION_ARGS  )

Definition at line 598 of file varlena.c.

599{
600 Datum txt = PG_GETARG_DATUM(0);
601
603}
#define TextDatumGetCString(d)
Definition: builtins.h:98

References PG_GETARG_DATUM, PG_RETURN_CSTRING, and TextDatumGetCString.

Referenced by pg_node_tree_out(), plsample_func_handler(), and plsample_trigger_handler().

◆ textoverlay()

Datum textoverlay ( PG_FUNCTION_ARGS  )

Definition at line 1101 of file varlena.c.

1102{
1103 text *t1 = PG_GETARG_TEXT_PP(0);
1104 text *t2 = PG_GETARG_TEXT_PP(1);
1105 int sp = PG_GETARG_INT32(2); /* substring start position */
1106 int sl = PG_GETARG_INT32(3); /* substring length */
1107
1108 PG_RETURN_TEXT_P(text_overlay(t1, t2, sp, sl));
1109}
static text * text_overlay(text *t1, text *t2, int sp, int sl)
Definition: varlena.c:1124

References PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, and text_overlay().

◆ textoverlay_no_len()

Datum textoverlay_no_len ( PG_FUNCTION_ARGS  )

Definition at line 1112 of file varlena.c.

1113{
1114 text *t1 = PG_GETARG_TEXT_PP(0);
1115 text *t2 = PG_GETARG_TEXT_PP(1);
1116 int sp = PG_GETARG_INT32(2); /* substring start position */
1117 int sl;
1118
1119 sl = text_length(PointerGetDatum(t2)); /* defaults to length(t2) */
1120 PG_RETURN_TEXT_P(text_overlay(t1, t2, sp, sl));
1121}

References PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_RETURN_TEXT_P, PointerGetDatum(), text_length(), and text_overlay().

◆ textpos()

Datum textpos ( PG_FUNCTION_ARGS  )

Definition at line 1161 of file varlena.c.

1162{
1164 text *search_str = PG_GETARG_TEXT_PP(1);
1165
1167}
static int text_position(text *t1, text *t2, Oid collid)
Definition: varlena.c:1184

References PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_INT32, str, and text_position().

◆ textrecv()

Datum textrecv ( PG_FUNCTION_ARGS  )

Definition at line 609 of file varlena.c.

610{
612 text *result;
613 char *str;
614 int nbytes;
615
616 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
617
618 result = cstring_to_text_with_len(str, nbytes);
619 pfree(str);
620 PG_RETURN_TEXT_P(result);
621}
char * pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
Definition: pqformat.c:546

References buf, cstring_to_text_with_len(), pfree(), PG_GETARG_POINTER, PG_RETURN_TEXT_P, pq_getmsgtext(), and str.

◆ textsend()

Datum textsend ( PG_FUNCTION_ARGS  )

Definition at line 627 of file varlena.c.

628{
629 text *t = PG_GETARG_TEXT_PP(0);
631
635}
void pq_sendtext(StringInfo buf, const char *str, int slen)
Definition: pqformat.c:172

References buf, PG_GETARG_TEXT_PP, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by bpcharsend(), pg_node_tree_send(), and varcharsend().

◆ textToQualifiedNameList()

List * textToQualifiedNameList ( text textval)

Definition at line 3467 of file varlena.c.

3468{
3469 char *rawname;
3470 List *result = NIL;
3471 List *namelist;
3472 ListCell *l;
3473
3474 /* Convert to C string (handles possible detoasting). */
3475 /* Note we rely on being able to modify rawname below. */
3476 rawname = text_to_cstring(textval);
3477
3478 if (!SplitIdentifierString(rawname, '.', &namelist))
3479 ereport(ERROR,
3480 (errcode(ERRCODE_INVALID_NAME),
3481 errmsg("invalid name syntax")));
3482
3483 if (namelist == NIL)
3484 ereport(ERROR,
3485 (errcode(ERRCODE_INVALID_NAME),
3486 errmsg("invalid name syntax")));
3487
3488 foreach(l, namelist)
3489 {
3490 char *curname = (char *) lfirst(l);
3491
3492 result = lappend(result, makeString(pstrdup(curname)));
3493 }
3494
3495 pfree(rawname);
3496 list_free(namelist);
3497
3498 return result;
3499}
void list_free(List *list)
Definition: list.c:1546
#define lfirst(lc)
Definition: pg_list.h:172
Definition: pg_list.h:54
String * makeString(char *str)
Definition: value.c:63
bool SplitIdentifierString(char *rawstring, char separator, List **namelist)
Definition: varlena.c:3525

References ereport, errcode(), errmsg(), ERROR, lappend(), lfirst, list_free(), makeString(), NIL, pfree(), pstrdup(), SplitIdentifierString(), and text_to_cstring().

Referenced by bt_metap(), bt_multi_page_stats(), bt_page_items_internal(), bt_page_stats_internal(), convert_table_name(), currtid_byrelname(), get_raw_page_internal(), get_rel_from_relname(), nextval(), pg_get_serial_sequence(), pg_get_viewdef_name(), pg_get_viewdef_name_ext(), pg_relpages(), pg_relpages_v1_5(), pgrowlocks(), pgstatindex(), pgstatindex_v1_5(), pgstattuple(), pgstattuple_v1_5(), row_security_active_name(), text_regclass(), ts_parse_byname(), and ts_token_type_byname().

◆ to_bin32()

Datum to_bin32 ( PG_FUNCTION_ARGS  )

Definition at line 5158 of file varlena.c.

5159{
5161
5163}
static text * convert_to_base(uint64 value, int base)
Definition: varlena.c:5132

References convert_to_base(), PG_GETARG_INT32, PG_RETURN_TEXT_P, and value.

◆ to_bin64()

Datum to_bin64 ( PG_FUNCTION_ARGS  )

Definition at line 5165 of file varlena.c.

5166{
5168
5170}

References convert_to_base(), PG_GETARG_INT64, PG_RETURN_TEXT_P, and value.

◆ to_hex32()

Datum to_hex32 ( PG_FUNCTION_ARGS  )

Definition at line 5196 of file varlena.c.

5197{
5199
5201}

References convert_to_base(), PG_GETARG_INT32, PG_RETURN_TEXT_P, and value.

Referenced by gin_page_opaque_info(), and gist_page_opaque_info().

◆ to_hex64()

Datum to_hex64 ( PG_FUNCTION_ARGS  )

Definition at line 5203 of file varlena.c.

5204{
5206
5208}

References convert_to_base(), PG_GETARG_INT64, PG_RETURN_TEXT_P, and value.

◆ to_oct32()

Datum to_oct32 ( PG_FUNCTION_ARGS  )

Definition at line 5177 of file varlena.c.

5178{
5180
5182}

References convert_to_base(), PG_GETARG_INT32, PG_RETURN_TEXT_P, and value.

◆ to_oct64()

Datum to_oct64 ( PG_FUNCTION_ARGS  )

Definition at line 5184 of file varlena.c.

5185{
5187
5189}

References convert_to_base(), PG_GETARG_INT64, PG_RETURN_TEXT_P, and value.

◆ unicode_assigned()

Datum unicode_assigned ( PG_FUNCTION_ARGS  )

Definition at line 6518 of file varlena.c.

6519{
6521 unsigned char *p;
6522 int size;
6523
6525 ereport(ERROR,
6526 (errmsg("Unicode categorization can only be performed if server encoding is UTF8")));
6527
6528 /* convert to pg_wchar */
6530 p = (unsigned char *) VARDATA_ANY(input);
6531 for (int i = 0; i < size; i++)
6532 {
6533 pg_wchar uchar = utf8_to_unicode(p);
6534 int category = unicode_category(uchar);
6535
6536 if (category == PG_U_UNASSIGNED)
6537 PG_RETURN_BOOL(false);
6538
6539 p += pg_utf_mblen(p);
6540 }
6541
6542 PG_RETURN_BOOL(true);
6543}
FILE * input
static pg_wchar utf8_to_unicode(const unsigned char *c)
Definition: mbprint.c:53
#define pg_utf_mblen
Definition: pg_wchar.h:633
pg_unicode_category unicode_category(pg_wchar code)
@ PG_U_UNASSIGNED

References ereport, errmsg(), ERROR, GetDatabaseEncoding(), i, input, PG_GETARG_TEXT_PP, pg_mbstrlen_with_len(), PG_RETURN_BOOL, PG_U_UNASSIGNED, PG_UTF8, pg_utf_mblen, unicode_category(), utf8_to_unicode(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ unicode_is_normalized()

Datum unicode_is_normalized ( PG_FUNCTION_ARGS  )

Definition at line 6612 of file varlena.c.

6613{
6615 char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
6617 int size;
6618 pg_wchar *input_chars;
6619 pg_wchar *output_chars;
6620 unsigned char *p;
6621 int i;
6622 UnicodeNormalizationQC quickcheck;
6623 int output_size;
6624 bool result;
6625
6626 form = unicode_norm_form_from_string(formstr);
6627
6628 /* convert to pg_wchar */
6630 input_chars = palloc((size + 1) * sizeof(pg_wchar));
6631 p = (unsigned char *) VARDATA_ANY(input);
6632 for (i = 0; i < size; i++)
6633 {
6634 input_chars[i] = utf8_to_unicode(p);
6635 p += pg_utf_mblen(p);
6636 }
6637 input_chars[i] = (pg_wchar) '\0';
6638 Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
6639
6640 /* quick check (see UAX #15) */
6641 quickcheck = unicode_is_normalized_quickcheck(form, input_chars);
6642 if (quickcheck == UNICODE_NORM_QC_YES)
6643 PG_RETURN_BOOL(true);
6644 else if (quickcheck == UNICODE_NORM_QC_NO)
6645 PG_RETURN_BOOL(false);
6646
6647 /* normalize and compare with original */
6648 output_chars = unicode_normalize(form, input_chars);
6649
6650 output_size = 0;
6651 for (pg_wchar *wp = output_chars; *wp; wp++)
6652 output_size++;
6653
6654 result = (size == output_size) &&
6655 (memcmp(input_chars, output_chars, size * sizeof(pg_wchar)) == 0);
6656
6657 PG_RETURN_BOOL(result);
6658}
UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input)
Definition: unicode_norm.c:598
pg_wchar * unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input)
Definition: unicode_norm.c:402
UnicodeNormalizationForm
Definition: unicode_norm.h:20
UnicodeNormalizationQC
Definition: unicode_norm.h:29
@ UNICODE_NORM_QC_YES
Definition: unicode_norm.h:31
@ UNICODE_NORM_QC_NO
Definition: unicode_norm.h:30
static UnicodeNormalizationForm unicode_norm_form_from_string(const char *formstr)
Definition: varlena.c:6458

References Assert(), i, input, palloc(), PG_GETARG_TEXT_PP, pg_mbstrlen_with_len(), PG_RETURN_BOOL, pg_utf_mblen, text_to_cstring(), unicode_is_normalized_quickcheck(), unicode_norm_form_from_string(), UNICODE_NORM_QC_NO, UNICODE_NORM_QC_YES, unicode_normalize(), utf8_to_unicode(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ unicode_norm_form_from_string()

static UnicodeNormalizationForm unicode_norm_form_from_string ( const char *  formstr)
static

Definition at line 6458 of file varlena.c.

6459{
6460 UnicodeNormalizationForm form = -1;
6461
6462 /*
6463 * Might as well check this while we're here.
6464 */
6466 ereport(ERROR,
6467 (errcode(ERRCODE_SYNTAX_ERROR),
6468 errmsg("Unicode normalization can only be performed if server encoding is UTF8")));
6469
6470 if (pg_strcasecmp(formstr, "NFC") == 0)
6471 form = UNICODE_NFC;
6472 else if (pg_strcasecmp(formstr, "NFD") == 0)
6473 form = UNICODE_NFD;
6474 else if (pg_strcasecmp(formstr, "NFKC") == 0)
6475 form = UNICODE_NFKC;
6476 else if (pg_strcasecmp(formstr, "NFKD") == 0)
6477 form = UNICODE_NFKD;
6478 else
6479 ereport(ERROR,
6480 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6481 errmsg("invalid normalization form: %s", formstr)));
6482
6483 return form;
6484}
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
@ UNICODE_NFKD
Definition: unicode_norm.h:24
@ UNICODE_NFD
Definition: unicode_norm.h:22
@ UNICODE_NFC
Definition: unicode_norm.h:21
@ UNICODE_NFKC
Definition: unicode_norm.h:23

References ereport, errcode(), errmsg(), ERROR, GetDatabaseEncoding(), pg_strcasecmp(), PG_UTF8, UNICODE_NFC, UNICODE_NFD, UNICODE_NFKC, and UNICODE_NFKD.

Referenced by unicode_is_normalized(), and unicode_normalize_func().

◆ unicode_normalize_func()

Datum unicode_normalize_func ( PG_FUNCTION_ARGS  )

Definition at line 6546 of file varlena.c.

6547{
6549 char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
6551 int size;
6552 pg_wchar *input_chars;
6553 pg_wchar *output_chars;
6554 unsigned char *p;
6555 text *result;
6556 int i;
6557
6558 form = unicode_norm_form_from_string(formstr);
6559
6560 /* convert to pg_wchar */
6562 input_chars = palloc((size + 1) * sizeof(pg_wchar));
6563 p = (unsigned char *) VARDATA_ANY(input);
6564 for (i = 0; i < size; i++)
6565 {
6566 input_chars[i] = utf8_to_unicode(p);
6567 p += pg_utf_mblen(p);
6568 }
6569 input_chars[i] = (pg_wchar) '\0';
6570 Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
6571
6572 /* action */
6573 output_chars = unicode_normalize(form, input_chars);
6574
6575 /* convert back to UTF-8 string */
6576 size = 0;
6577 for (pg_wchar *wp = output_chars; *wp; wp++)
6578 {
6579 unsigned char buf[4];
6580
6581 unicode_to_utf8(*wp, buf);
6582 size += pg_utf_mblen(buf);
6583 }
6584
6585 result = palloc(size + VARHDRSZ);
6586 SET_VARSIZE(result, size + VARHDRSZ);
6587
6588 p = (unsigned char *) VARDATA_ANY(result);
6589 for (pg_wchar *wp = output_chars; *wp; wp++)
6590 {
6591 unicode_to_utf8(*wp, p);
6592 p += pg_utf_mblen(p);
6593 }
6594 Assert((char *) p == (char *) result + size + VARHDRSZ);
6595
6596 PG_RETURN_TEXT_P(result);
6597}
static unsigned char * unicode_to_utf8(pg_wchar c, unsigned char *utf8string)
Definition: pg_wchar.h:575

References Assert(), buf, i, input, palloc(), PG_GETARG_TEXT_PP, pg_mbstrlen_with_len(), PG_RETURN_TEXT_P, pg_utf_mblen, SET_VARSIZE, text_to_cstring(), unicode_norm_form_from_string(), unicode_normalize(), unicode_to_utf8(), utf8_to_unicode(), VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

◆ unicode_version()

Datum unicode_version ( PG_FUNCTION_ARGS  )

Definition at line 6495 of file varlena.c.

6496{
6498}
#define PG_UNICODE_VERSION

References cstring_to_text(), PG_RETURN_TEXT_P, and PG_UNICODE_VERSION.

◆ unistr()

Datum unistr ( PG_FUNCTION_ARGS  )

Definition at line 6704 of file varlena.c.

6705{
6706 text *input_text = PG_GETARG_TEXT_PP(0);
6707 char *instr;
6708 int len;
6710 text *result;
6711 pg_wchar pair_first = 0;
6712 char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
6713
6714 instr = VARDATA_ANY(input_text);
6715 len = VARSIZE_ANY_EXHDR(input_text);
6716
6718
6719 while (len > 0)
6720 {
6721 if (instr[0] == '\\')
6722 {
6723 if (len >= 2 &&
6724 instr[1] == '\\')
6725 {
6726 if (pair_first)
6727 goto invalid_pair;
6728 appendStringInfoChar(&str, '\\');
6729 instr += 2;
6730 len -= 2;
6731 }
6732 else if ((len >= 5 && isxdigits_n(instr + 1, 4)) ||
6733 (len >= 6 && instr[1] == 'u' && isxdigits_n(instr + 2, 4)))
6734 {
6735 pg_wchar unicode;
6736 int offset = instr[1] == 'u' ? 2 : 1;
6737
6738 unicode = hexval_n(instr + offset, 4);
6739
6740 if (!is_valid_unicode_codepoint(unicode))
6741 ereport(ERROR,
6742 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6743 errmsg("invalid Unicode code point: %04X", unicode));
6744
6745 if (pair_first)
6746 {
6747 if (is_utf16_surrogate_second(unicode))
6748 {
6749 unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6750 pair_first = 0;
6751 }
6752 else
6753 goto invalid_pair;
6754 }
6755 else if (is_utf16_surrogate_second(unicode))
6756 goto invalid_pair;
6757
6758 if (is_utf16_surrogate_first(unicode))
6759 pair_first = unicode;
6760 else
6761 {
6762 pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6764 }
6765
6766 instr += 4 + offset;
6767 len -= 4 + offset;
6768 }
6769 else if (len >= 8 && instr[1] == '+' && isxdigits_n(instr + 2, 6))
6770 {
6771 pg_wchar unicode;
6772
6773 unicode = hexval_n(instr + 2, 6);
6774
6775 if (!is_valid_unicode_codepoint(unicode))
6776 ereport(ERROR,
6777 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6778 errmsg("invalid Unicode code point: %04X", unicode));
6779
6780 if (pair_first)
6781 {
6782 if (is_utf16_surrogate_second(unicode))
6783 {
6784 unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6785 pair_first = 0;
6786 }
6787 else
6788 goto invalid_pair;
6789 }
6790 else if (is_utf16_surrogate_second(unicode))
6791 goto invalid_pair;
6792
6793 if (is_utf16_surrogate_first(unicode))
6794 pair_first = unicode;
6795 else
6796 {
6797 pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6799 }
6800
6801 instr += 8;
6802 len -= 8;
6803 }
6804 else if (len >= 10 && instr[1] == 'U' && isxdigits_n(instr + 2, 8))
6805 {
6806 pg_wchar unicode;
6807
6808 unicode = hexval_n(instr + 2, 8);
6809
6810 if (!is_valid_unicode_codepoint(unicode))
6811 ereport(ERROR,
6812 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6813 errmsg("invalid Unicode code point: %04X", unicode));
6814
6815 if (pair_first)
6816 {
6817 if (is_utf16_surrogate_second(unicode))
6818 {
6819 unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6820 pair_first = 0;
6821 }
6822 else
6823 goto invalid_pair;
6824 }
6825 else if (is_utf16_surrogate_second(unicode))
6826 goto invalid_pair;
6827
6828 if (is_utf16_surrogate_first(unicode))
6829 pair_first = unicode;
6830 else
6831 {
6832 pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6834 }
6835
6836 instr += 10;
6837 len -= 10;
6838 }
6839 else
6840 ereport(ERROR,
6841 (errcode(ERRCODE_SYNTAX_ERROR),
6842 errmsg("invalid Unicode escape"),
6843 errhint("Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX.")));
6844 }
6845 else
6846 {
6847 if (pair_first)
6848 goto invalid_pair;
6849
6850 appendStringInfoChar(&str, *instr++);
6851 len--;
6852 }
6853 }
6854
6855 /* unfinished surrogate pair? */
6856 if (pair_first)
6857 goto invalid_pair;
6858
6859 result = cstring_to_text_with_len(str.data, str.len);
6860 pfree(str.data);
6861
6862 PG_RETURN_TEXT_P(result);
6863
6864invalid_pair:
6865 ereport(ERROR,
6866 (errcode(ERRCODE_SYNTAX_ERROR),
6867 errmsg("invalid Unicode surrogate pair")));
6868 PG_RETURN_NULL(); /* keep compiler quiet */
6869}
void pg_unicode_to_server(pg_wchar c, unsigned char *s)
Definition: mbutils.c:864
#define MAX_UNICODE_EQUIVALENT_STRING
Definition: pg_wchar.h:329
static bool is_valid_unicode_codepoint(pg_wchar c)
Definition: pg_wchar.h:519
static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
Definition: pg_wchar.h:537
static bool is_utf16_surrogate_first(pg_wchar c)
Definition: pg_wchar.h:525
static bool is_utf16_surrogate_second(pg_wchar c)
Definition: pg_wchar.h:531
static unsigned int hexval_n(const char *instr, size_t n)
Definition: varlena.c:6690
static bool isxdigits_n(const char *instr, size_t n)
Definition: varlena.c:6664

References appendStringInfoChar(), appendStringInfoString(), cstring_to_text_with_len(), ereport, errcode(), errhint(), errmsg(), ERROR, hexval_n(), initStringInfo(), is_utf16_surrogate_first(), is_utf16_surrogate_second(), is_valid_unicode_codepoint(), isxdigits_n(), len, MAX_UNICODE_EQUIVALENT_STRING, pfree(), PG_GETARG_TEXT_PP, PG_RETURN_NULL, PG_RETURN_TEXT_P, pg_unicode_to_server(), str, surrogate_pair_to_codepoint(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ unknownin()

Datum unknownin ( PG_FUNCTION_ARGS  )

Definition at line 642 of file varlena.c.

643{
644 char *str = PG_GETARG_CSTRING(0);
645
646 /* representation is same as cstring */
648}

References PG_GETARG_CSTRING, PG_RETURN_CSTRING, pstrdup(), and str.

◆ unknownout()

Datum unknownout ( PG_FUNCTION_ARGS  )

Definition at line 654 of file varlena.c.

655{
656 /* representation is same as cstring */
657 char *str = PG_GETARG_CSTRING(0);
658
660}

References PG_GETARG_CSTRING, PG_RETURN_CSTRING, pstrdup(), and str.

◆ unknownrecv()

Datum unknownrecv ( PG_FUNCTION_ARGS  )

Definition at line 666 of file varlena.c.

667{
669 char *str;
670 int nbytes;
671
672 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
673 /* representation is same as cstring */
675}

References buf, PG_GETARG_POINTER, PG_RETURN_CSTRING, pq_getmsgtext(), and str.

◆ unknownsend()

Datum unknownsend ( PG_FUNCTION_ARGS  )

Definition at line 681 of file varlena.c.

682{
683 /* representation is same as cstring */
684 char *str = PG_GETARG_CSTRING(0);
686
688 pq_sendtext(&buf, str, strlen(str));
690}

References buf, PG_GETARG_CSTRING, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendtext(), and str.

◆ updateClosestMatch()

void updateClosestMatch ( ClosestMatchState state,
const char *  candidate 
)

Definition at line 6410 of file varlena.c.

6411{
6412 int dist;
6413
6414 Assert(state);
6415
6416 if (state->source == NULL || state->source[0] == '\0' ||
6417 candidate == NULL || candidate[0] == '\0')
6418 return;
6419
6420 /*
6421 * To avoid ERROR-ing, we check the lengths here instead of setting
6422 * 'trusted' to false in the call to varstr_levenshtein_less_equal().
6423 */
6424 if (strlen(state->source) > MAX_LEVENSHTEIN_STRLEN ||
6425 strlen(candidate) > MAX_LEVENSHTEIN_STRLEN)
6426 return;
6427
6428 dist = varstr_levenshtein_less_equal(state->source, strlen(state->source),
6429 candidate, strlen(candidate), 1, 1, 1,
6430 state->max_d, true);
6431 if (dist <= state->max_d &&
6432 dist <= strlen(state->source) / 2 &&
6433 (state->min_d == -1 || dist < state->min_d))
6434 {
6435 state->min_d = dist;
6436 state->match = candidate;
6437 }
6438}
#define MAX_LEVENSHTEIN_STRLEN
Definition: levenshtein.c:26
int varstr_levenshtein_less_equal(const char *source, int slen, const char *target, int tlen, int ins_c, int del_c, int sub_c, int max_d, bool trusted)

References Assert(), MAX_LEVENSHTEIN_STRLEN, and varstr_levenshtein_less_equal().

Referenced by dblink_fdw_validator(), file_fdw_validator(), postgres_fdw_validator(), and postgresql_fdw_validator().

◆ varlenafastcmp_locale()

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

Definition at line 2147 of file varlena.c.

2148{
2151 char *a1p,
2152 *a2p;
2153 int len1,
2154 len2,
2155 result;
2156
2157 a1p = VARDATA_ANY(arg1);
2158 a2p = VARDATA_ANY(arg2);
2159
2160 len1 = VARSIZE_ANY_EXHDR(arg1);
2161 len2 = VARSIZE_ANY_EXHDR(arg2);
2162
2163 result = varstrfastcmp_locale(a1p, len1, a2p, len2, ssup);
2164
2165 /* We can't afford to leak memory here. */
2166 if (PointerGetDatum(arg1) != x)
2167 pfree(arg1);
2168 if (PointerGetDatum(arg2) != y)
2169 pfree(arg2);
2170
2171 return result;
2172}
#define DatumGetVarStringPP(X)
Definition: varlena.c:125

References DatumGetVarStringPP, pfree(), PointerGetDatum(), VARDATA_ANY, VARSIZE_ANY_EXHDR, varstrfastcmp_locale(), x, and y.

Referenced by varstr_sortsupport().

◆ varstr_abbrev_abort()

static bool varstr_abbrev_abort ( int  memtupcount,
SortSupport  ssup 
)
static

Definition at line 2490 of file varlena.c.

2491{
2493 double abbrev_distinct,
2494 key_distinct;
2495
2496 Assert(ssup->abbreviate);
2497
2498 /* Have a little patience */
2499 if (memtupcount < 100)
2500 return false;
2501
2502 abbrev_distinct = estimateHyperLogLog(&sss->abbr_card);
2503 key_distinct = estimateHyperLogLog(&sss->full_card);
2504
2505 /*
2506 * Clamp cardinality estimates to at least one distinct value. While
2507 * NULLs are generally disregarded, if only NULL values were seen so far,
2508 * that might misrepresent costs if we failed to clamp.
2509 */
2510 if (abbrev_distinct <= 1.0)
2511 abbrev_distinct = 1.0;
2512
2513 if (key_distinct <= 1.0)
2514 key_distinct = 1.0;
2515
2516 /*
2517 * In the worst case all abbreviated keys are identical, while at the same
2518 * time there are differences within full key strings not captured in
2519 * abbreviations.
2520 */
2521 if (trace_sort)
2522 {
2523 double norm_abbrev_card = abbrev_distinct / (double) memtupcount;
2524
2525 elog(LOG, "varstr_abbrev: abbrev_distinct after %d: %f "
2526 "(key_distinct: %f, norm_abbrev_card: %f, prop_card: %f)",
2527 memtupcount, abbrev_distinct, key_distinct, norm_abbrev_card,
2528 sss->prop_card);
2529 }
2530
2531 /*
2532 * If the number of distinct abbreviated keys approximately matches the
2533 * number of distinct authoritative original keys, that's reason enough to
2534 * proceed. We can win even with a very low cardinality set if most
2535 * tie-breakers only memcmp(). This is by far the most important
2536 * consideration.
2537 *
2538 * While comparisons that are resolved at the abbreviated key level are
2539 * considerably cheaper than tie-breakers resolved with memcmp(), both of
2540 * those two outcomes are so much cheaper than a full strcoll() once
2541 * sorting is underway that it doesn't seem worth it to weigh abbreviated
2542 * cardinality against the overall size of the set in order to more
2543 * accurately model costs. Assume that an abbreviated comparison, and an
2544 * abbreviated comparison with a cheap memcmp()-based authoritative
2545 * resolution are equivalent.
2546 */
2547 if (abbrev_distinct > key_distinct * sss->prop_card)
2548 {
2549 /*
2550 * When we have exceeded 10,000 tuples, decay required cardinality
2551 * aggressively for next call.
2552 *
2553 * This is useful because the number of comparisons required on
2554 * average increases at a linearithmic rate, and at roughly 10,000
2555 * tuples that factor will start to dominate over the linear costs of
2556 * string transformation (this is a conservative estimate). The decay
2557 * rate is chosen to be a little less aggressive than halving -- which
2558 * (since we're called at points at which memtupcount has doubled)
2559 * would never see the cost model actually abort past the first call
2560 * following a decay. This decay rate is mostly a precaution against
2561 * a sudden, violent swing in how well abbreviated cardinality tracks
2562 * full key cardinality. The decay also serves to prevent a marginal
2563 * case from being aborted too late, when too much has already been
2564 * invested in string transformation.
2565 *
2566 * It's possible for sets of several million distinct strings with
2567 * mere tens of thousands of distinct abbreviated keys to still
2568 * benefit very significantly. This will generally occur provided
2569 * each abbreviated key is a proxy for a roughly uniform number of the
2570 * set's full keys. If it isn't so, we hope to catch that early and
2571 * abort. If it isn't caught early, by the time the problem is
2572 * apparent it's probably not worth aborting.
2573 */
2574 if (memtupcount > 10000)
2575 sss->prop_card *= 0.65;
2576
2577 return false;
2578 }
2579
2580 /*
2581 * Abort abbreviation strategy.
2582 *
2583 * The worst case, where all abbreviated keys are identical while all
2584 * original strings differ will typically only see a regression of about
2585 * 10% in execution time for small to medium sized lists of strings.
2586 * Whereas on modern CPUs where cache stalls are the dominant cost, we can
2587 * often expect very large improvements, particularly with sets of strings
2588 * of moderately high to high abbreviated cardinality. There is little to
2589 * lose but much to gain, which our strategy reflects.
2590 */
2591 if (trace_sort)
2592 elog(LOG, "varstr_abbrev: aborted abbreviation at %d "
2593 "(abbrev_distinct: %f, key_distinct: %f, prop_card: %f)",
2594 memtupcount, abbrev_distinct, key_distinct, sss->prop_card);
2595
2596 return true;
2597}
#define LOG
Definition: elog.h:31
double estimateHyperLogLog(hyperLogLogState *cState)
Definition: hyperloglog.c:186
void * ssup_extra
Definition: sortsupport.h:87
hyperLogLogState full_card
Definition: varlena.c:102
hyperLogLogState abbr_card
Definition: varlena.c:101
bool trace_sort
Definition: tuplesort.c:124

References VarStringSortSupport::abbr_card, SortSupportData::abbreviate, Assert(), elog, estimateHyperLogLog(), VarStringSortSupport::full_card, LOG, VarStringSortSupport::prop_card, SortSupportData::ssup_extra, and trace_sort.

Referenced by varstr_sortsupport().

◆ varstr_abbrev_convert()

static Datum varstr_abbrev_convert ( Datum  original,
SortSupport  ssup 
)
static

Definition at line 2292 of file varlena.c.

2293{
2294 const size_t max_prefix_bytes = sizeof(Datum);
2296 VarString *authoritative = DatumGetVarStringPP(original);
2297 char *authoritative_data = VARDATA_ANY(authoritative);
2298
2299 /* working state */
2300 Datum res;
2301 char *pres;
2302 int len;
2303 uint32 hash;
2304
2305 pres = (char *) &res;
2306 /* memset(), so any non-overwritten bytes are NUL */
2307 memset(pres, 0, max_prefix_bytes);
2308 len = VARSIZE_ANY_EXHDR(authoritative);
2309
2310 /* Get number of bytes, ignoring trailing spaces */
2311 if (sss->typid == BPCHAROID)
2312 len = bpchartruelen(authoritative_data, len);
2313
2314 /*
2315 * If we're using the C collation, use memcpy(), rather than strxfrm(), to
2316 * abbreviate keys. The full comparator for the C locale is always
2317 * memcmp(). It would be incorrect to allow bytea callers (callers that
2318 * always force the C collation -- bytea isn't a collatable type, but this
2319 * approach is convenient) to use strxfrm(). This is because bytea
2320 * strings may contain NUL bytes. Besides, this should be faster, too.
2321 *
2322 * More generally, it's okay that bytea callers can have NUL bytes in
2323 * strings because abbreviated cmp need not make a distinction between
2324 * terminating NUL bytes, and NUL bytes representing actual NULs in the
2325 * authoritative representation. Hopefully a comparison at or past one
2326 * abbreviated key's terminating NUL byte will resolve the comparison
2327 * without consulting the authoritative representation; specifically, some
2328 * later non-NUL byte in the longer string can resolve the comparison
2329 * against a subsequent terminating NUL in the shorter string. There will
2330 * usually be what is effectively a "length-wise" resolution there and
2331 * then.
2332 *
2333 * If that doesn't work out -- if all bytes in the longer string
2334 * positioned at or past the offset of the smaller string's (first)
2335 * terminating NUL are actually representative of NUL bytes in the
2336 * authoritative binary string (perhaps with some *terminating* NUL bytes
2337 * towards the end of the longer string iff it happens to still be small)
2338 * -- then an authoritative tie-breaker will happen, and do the right
2339 * thing: explicitly consider string length.
2340 */
2341 if (sss->collate_c)
2342 memcpy(pres, authoritative_data, Min(len, max_prefix_bytes));
2343 else
2344 {
2345 Size bsize;
2346
2347 /*
2348 * We're not using the C collation, so fall back on strxfrm or ICU
2349 * analogs.
2350 */
2351
2352 /* By convention, we use buffer 1 to store and NUL-terminate */
2353 if (len >= sss->buflen1)
2354 {
2355 sss->buflen1 = Max(len + 1, Min(sss->buflen1 * 2, MaxAllocSize));
2356 sss->buf1 = repalloc(sss->buf1, sss->buflen1);
2357 }
2358
2359 /* Might be able to reuse strxfrm() blob from last call */
2360 if (sss->last_len1 == len && sss->cache_blob &&
2361 memcmp(sss->buf1, authoritative_data, len) == 0)
2362 {
2363 memcpy(pres, sss->buf2, Min(max_prefix_bytes, sss->last_len2));
2364 /* No change affecting cardinality, so no hashing required */
2365 goto done;
2366 }
2367
2368 memcpy(sss->buf1, authoritative_data, len);
2369
2370 /*
2371 * pg_strxfrm() and pg_strxfrm_prefix expect NUL-terminated strings.
2372 */
2373 sss->buf1[len] = '\0';
2374 sss->last_len1 = len;
2375
2377 {
2378 if (sss->buflen2 < max_prefix_bytes)
2379 {
2380 sss->buflen2 = Max(max_prefix_bytes,
2381 Min(sss->buflen2 * 2, MaxAllocSize));
2382 sss->buf2 = repalloc(sss->buf2, sss->buflen2);
2383 }
2384
2385 bsize = pg_strxfrm_prefix(sss->buf2, sss->buf1,
2386 max_prefix_bytes, sss->locale);
2387 sss->last_len2 = bsize;
2388 }
2389 else
2390 {
2391 /*
2392 * Loop: Call pg_strxfrm(), possibly enlarge buffer, and try
2393 * again. The pg_strxfrm() function leaves the result buffer
2394 * content undefined if the result did not fit, so we need to
2395 * retry until everything fits, even though we only need the first
2396 * few bytes in the end.
2397 */
2398 for (;;)
2399 {
2400 bsize = pg_strxfrm(sss->buf2, sss->buf1, sss->buflen2,
2401 sss->locale);
2402
2403 sss->last_len2 = bsize;
2404 if (bsize < sss->buflen2)
2405 break;
2406
2407 /*
2408 * Grow buffer and retry.
2409 */
2410 sss->buflen2 = Max(bsize + 1,
2411 Min(sss->buflen2 * 2, MaxAllocSize));
2412 sss->buf2 = repalloc(sss->buf2, sss->buflen2);
2413 }
2414 }
2415
2416 /*
2417 * Every Datum byte is always compared. This is safe because the
2418 * strxfrm() blob is itself NUL terminated, leaving no danger of
2419 * misinterpreting any NUL bytes not intended to be interpreted as
2420 * logically representing termination.
2421 *
2422 * (Actually, even if there were NUL bytes in the blob it would be
2423 * okay. See remarks on bytea case above.)
2424 */
2425 memcpy(pres, sss->buf2, Min(max_prefix_bytes, bsize));
2426 }
2427
2428 /*
2429 * Maintain approximate cardinality of both abbreviated keys and original,
2430 * authoritative keys using HyperLogLog. Used as cheap insurance against
2431 * the worst case, where we do many string transformations for no saving
2432 * in full strcoll()-based comparisons. These statistics are used by
2433 * varstr_abbrev_abort().
2434 *
2435 * First, Hash key proper, or a significant fraction of it. Mix in length
2436 * in order to compensate for cases where differences are past
2437 * PG_CACHE_LINE_SIZE bytes, so as to limit the overhead of hashing.
2438 */
2439 hash = DatumGetUInt32(hash_any((unsigned char *) authoritative_data,
2441
2442 if (len > PG_CACHE_LINE_SIZE)
2444
2446
2447 /* Hash abbreviated key */
2448#if SIZEOF_DATUM == 8
2449 {
2450 uint32 lohalf,
2451 hihalf;
2452
2453 lohalf = (uint32) res;
2454 hihalf = (uint32) (res >> 32);
2455 hash = DatumGetUInt32(hash_uint32(lohalf ^ hihalf));
2456 }
2457#else /* SIZEOF_DATUM != 8 */
2459#endif
2460
2462
2463 /* Cache result, perhaps saving an expensive strxfrm() call next time */
2464 sss->cache_blob = true;
2465done:
2466
2467 /*
2468 * Byteswap on little-endian machines.
2469 *
2470 * This is needed so that ssup_datum_unsigned_cmp() (an unsigned integer
2471 * 3-way comparator) works correctly on all platforms. If we didn't do
2472 * this, the comparator would have to call memcmp() with a pair of
2473 * pointers to the first byte of each abbreviated key, which is slower.
2474 */
2475 res = DatumBigEndianToNative(res);
2476
2477 /* Don't leak memory here */
2478 if (PointerGetDatum(authoritative) != original)
2479 pfree(authoritative);
2480
2481 return res;
2482}
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
Definition: hyperloglog.c:167
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1544
#define PG_CACHE_LINE_SIZE
bool pg_strxfrm_prefix_enabled(pg_locale_t locale)
Definition: pg_locale.c:1422
size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale)
Definition: pg_locale.c:1386
size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, pg_locale_t locale)
Definition: pg_locale.c:1433
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:227
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715
pg_locale_t locale
Definition: varlena.c:104

References VarStringSortSupport::abbr_card, addHyperLogLog(), bpchartruelen(), VarStringSortSupport::buf1, VarStringSortSupport::buf2, VarStringSortSupport::buflen1, VarStringSortSupport::buflen2, VarStringSortSupport::cache_blob, VarStringSortSupport::collate_c, DatumGetUInt32(), DatumGetVarStringPP, VarStringSortSupport::full_card, hash(), hash_any(), hash_uint32(), VarStringSortSupport::last_len1, VarStringSortSupport::last_len2, len, VarStringSortSupport::locale, Max, MaxAllocSize, Min, pfree(), PG_CACHE_LINE_SIZE, pg_strxfrm(), pg_strxfrm_prefix(), pg_strxfrm_prefix_enabled(), PointerGetDatum(), repalloc(), SortSupportData::ssup_extra, VarStringSortSupport::typid, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by varstr_sortsupport().

◆ varstr_cmp()

int varstr_cmp ( const char *  arg1,
int  len1,
const char *  arg2,
int  len2,
Oid  collid 
)

Definition at line 1610 of file varlena.c.

1611{
1612 int result;
1613 pg_locale_t mylocale;
1614
1616
1618
1619 if (mylocale->collate_is_c)
1620 {
1621 result = memcmp(arg1, arg2, Min(len1, len2));
1622 if ((result == 0) && (len1 != len2))
1623 result = (len1 < len2) ? -1 : 1;
1624 }
1625 else
1626 {
1627 /*
1628 * memcmp() can't tell us which of two unequal strings sorts first,
1629 * but it's a cheap way to tell if they're equal. Testing shows that
1630 * memcmp() followed by strcoll() is only trivially slower than
1631 * strcoll() by itself, so we don't lose much if this doesn't work out
1632 * very often, and if it does - for example, because there are many
1633 * equal strings in the input - then we win big by avoiding expensive
1634 * collation-aware comparisons.
1635 */
1636 if (len1 == len2 && memcmp(arg1, arg2, len1) == 0)
1637 return 0;
1638
1639 result = pg_strncoll(arg1, len1, arg2, len2, mylocale);
1640
1641 /* Break tie if necessary. */
1642 if (result == 0 && mylocale->deterministic)
1643 {
1644 result = memcmp(arg1, arg2, Min(len1, len2));
1645 if ((result == 0) && (len1 != len2))
1646 result = (len1 < len2) ? -1 : 1;
1647 }
1648 }
1649
1650 return result;
1651}

References check_collation_set(), pg_locale_struct::collate_is_c, collid, pg_locale_struct::deterministic, Min, pg_newlocale_from_collation(), and pg_strncoll().

Referenced by bpchar_larger(), bpchar_smaller(), bpcharcmp(), bpchareq(), bpcharge(), bpchargt(), bpcharle(), bpcharlt(), bpcharne(), btnametextcmp(), bttextnamecmp(), citextcmp(), compareJsonbScalarValue(), gin_compare_jsonb(), make_greater_string(), namecmp(), nameeqtext(), namenetext(), spg_text_leaf_consistent(), text_cmp(), texteqname(), and textnename().

◆ varstr_sortsupport()

void varstr_sortsupport ( SortSupport  ssup,
Oid  typid,
Oid  collid 
)

Definition at line 1928 of file varlena.c.

1929{
1930 bool abbreviate = ssup->abbreviate;
1931 bool collate_c = false;
1934
1936
1938
1939 /*
1940 * If possible, set ssup->comparator to a function which can be used to
1941 * directly compare two datums. If we can do this, we'll avoid the
1942 * overhead of a trip through the fmgr layer for every comparison, which
1943 * can be substantial.
1944 *
1945 * Most typically, we'll set the comparator to varlenafastcmp_locale,
1946 * which uses strcoll() to perform comparisons. We use that for the
1947 * BpChar case too, but type NAME uses namefastcmp_locale. However, if
1948 * LC_COLLATE = C, we can make things quite a bit faster with
1949 * varstrfastcmp_c, bpcharfastcmp_c, or namefastcmp_c, all of which use
1950 * memcmp() rather than strcoll().
1951 */
1952 if (locale->collate_is_c)
1953 {
1954 if (typid == BPCHAROID)
1956 else if (typid == NAMEOID)
1957 {
1958 ssup->comparator = namefastcmp_c;
1959 /* Not supporting abbreviation with type NAME, for now */
1960 abbreviate = false;
1961 }
1962 else
1964
1965 collate_c = true;
1966 }
1967 else
1968 {
1969 /*
1970 * We use varlenafastcmp_locale except for type NAME.
1971 */
1972 if (typid == NAMEOID)
1973 {
1975 /* Not supporting abbreviation with type NAME, for now */
1976 abbreviate = false;
1977 }
1978 else
1980
1981 /*
1982 * Unfortunately, it seems that abbreviation for non-C collations is
1983 * broken on many common platforms; see pg_strxfrm_enabled().
1984 *
1985 * Even apart from the risk of broken locales, it's possible that
1986 * there are platforms where the use of abbreviated keys should be
1987 * disabled at compile time. Having only 4 byte datums could make
1988 * worst-case performance drastically more likely, for example.
1989 * Moreover, macOS's strxfrm() implementation is known to not
1990 * effectively concentrate a significant amount of entropy from the
1991 * original string in earlier transformed blobs. It's possible that
1992 * other supported platforms are similarly encumbered. So, if we ever
1993 * get past disabling this categorically, we may still want or need to
1994 * disable it for particular platforms.
1995 */
1997 abbreviate = false;
1998 }
1999
2000 /*
2001 * If we're using abbreviated keys, or if we're using a locale-aware
2002 * comparison, we need to initialize a VarStringSortSupport object. Both
2003 * cases will make use of the temporary buffers we initialize here for
2004 * scratch space (and to detect requirement for BpChar semantics from
2005 * caller), and the abbreviation case requires additional state.
2006 */
2007 if (abbreviate || !collate_c)
2008 {
2009 sss = palloc(sizeof(VarStringSortSupport));
2010 sss->buf1 = palloc(TEXTBUFLEN);
2011 sss->buflen1 = TEXTBUFLEN;
2012 sss->buf2 = palloc(TEXTBUFLEN);
2013 sss->buflen2 = TEXTBUFLEN;
2014 /* Start with invalid values */
2015 sss->last_len1 = -1;
2016 sss->last_len2 = -1;
2017 /* Initialize */
2018 sss->last_returned = 0;
2019 if (collate_c)
2020 sss->locale = NULL;
2021 else
2022 sss->locale = locale;
2023
2024 /*
2025 * To avoid somehow confusing a strxfrm() blob and an original string,
2026 * constantly keep track of the variety of data that buf1 and buf2
2027 * currently contain.
2028 *
2029 * Comparisons may be interleaved with conversion calls. Frequently,
2030 * conversions and comparisons are batched into two distinct phases,
2031 * but the correctness of caching cannot hinge upon this. For
2032 * comparison caching, buffer state is only trusted if cache_blob is
2033 * found set to false, whereas strxfrm() caching only trusts the state
2034 * when cache_blob is found set to true.
2035 *
2036 * Arbitrarily initialize cache_blob to true.
2037 */
2038 sss->cache_blob = true;
2039 sss->collate_c = collate_c;
2040 sss->typid = typid;
2041 ssup->ssup_extra = sss;
2042
2043 /*
2044 * If possible, plan to use the abbreviated keys optimization. The
2045 * core code may switch back to authoritative comparator should
2046 * abbreviation be aborted.
2047 */
2048 if (abbreviate)
2049 {
2050 sss->prop_card = 0.20;
2051 initHyperLogLog(&sss->abbr_card, 10);
2052 initHyperLogLog(&sss->full_card, 10);
2053 ssup->abbrev_full_comparator = ssup->comparator;
2057 }
2058 }
2059}
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
Definition: hyperloglog.c:66
bool pg_strxfrm_enabled(pg_locale_t locale)
Definition: pg_locale.c:1370
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:172
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:191
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
Definition: sortsupport.h:182
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3139
static bool varstr_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: varlena.c:2490
static int varlenafastcmp_locale(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2147
static int bpcharfastcmp_c(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2102
static int namefastcmp_c(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2135
static int namefastcmp_locale(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2178
static Datum varstr_abbrev_convert(Datum original, SortSupport ssup)
Definition: varlena.c:2292
static int varstrfastcmp_c(Datum x, Datum y, SortSupport ssup)
Definition: varlena.c:2065
#define TEXTBUFLEN
Definition: varlena.c:122

References VarStringSortSupport::abbr_card, SortSupportData::abbrev_abort, SortSupportData::abbrev_converter, SortSupportData::abbrev_full_comparator, SortSupportData::abbreviate, bpcharfastcmp_c(), VarStringSortSupport::buf1, VarStringSortSupport::buf2, VarStringSortSupport::buflen1, VarStringSortSupport::buflen2, VarStringSortSupport::cache_blob, check_collation_set(), VarStringSortSupport::collate_c, collid, SortSupportData::comparator, VarStringSortSupport::full_card, initHyperLogLog(), VarStringSortSupport::last_len1, VarStringSortSupport::last_len2, VarStringSortSupport::last_returned, VarStringSortSupport::locale, locale, namefastcmp_c(), namefastcmp_locale(), palloc(), pg_newlocale_from_collation(), pg_strxfrm_enabled(), VarStringSortSupport::prop_card, ssup_datum_unsigned_cmp(), SortSupportData::ssup_extra, TEXTBUFLEN, VarStringSortSupport::typid, varlenafastcmp_locale(), varstr_abbrev_abort(), varstr_abbrev_convert(), and varstrfastcmp_c().

Referenced by bpchar_sortsupport(), btbpchar_pattern_sortsupport(), btnamesortsupport(), bttext_pattern_sortsupport(), bttextsortsupport(), and bytea_sortsupport().

◆ varstrfastcmp_c()

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

Definition at line 2065 of file varlena.c.

2066{
2069 char *a1p,
2070 *a2p;
2071 int len1,
2072 len2,
2073 result;
2074
2075 a1p = VARDATA_ANY(arg1);
2076 a2p = VARDATA_ANY(arg2);
2077
2078 len1 = VARSIZE_ANY_EXHDR(arg1);
2079 len2 = VARSIZE_ANY_EXHDR(arg2);
2080
2081 result = memcmp(a1p, a2p, Min(len1, len2));
2082 if ((result == 0) && (len1 != len2))
2083 result = (len1 < len2) ? -1 : 1;
2084
2085 /* We can't afford to leak memory here. */
2086 if (PointerGetDatum(arg1) != x)
2087 pfree(arg1);
2088 if (PointerGetDatum(arg2) != y)
2089 pfree(arg2);
2090
2091 return result;
2092}

References DatumGetVarStringPP, Min, pfree(), PointerGetDatum(), VARDATA_ANY, VARSIZE_ANY_EXHDR, x, and y.

Referenced by varstr_sortsupport().

◆ varstrfastcmp_locale()

static int varstrfastcmp_locale ( char *  a1p,
int  len1,
char *  a2p,
int  len2,
SortSupport  ssup 
)
static

Definition at line 2192 of file varlena.c.

2193{
2195 int result;
2196 bool arg1_match;
2197
2198 /* Fast pre-check for equality, as discussed in varstr_cmp() */
2199 if (len1 == len2 && memcmp(a1p, a2p, len1) == 0)
2200 {
2201 /*
2202 * No change in buf1 or buf2 contents, so avoid changing last_len1 or
2203 * last_len2. Existing contents of buffers might still be used by
2204 * next call.
2205 *
2206 * It's fine to allow the comparison of BpChar padding bytes here,
2207 * even though that implies that the memcmp() will usually be
2208 * performed for BpChar callers (though multibyte characters could
2209 * still prevent that from occurring). The memcmp() is still very
2210 * cheap, and BpChar's funny semantics have us remove trailing spaces
2211 * (not limited to padding), so we need make no distinction between
2212 * padding space characters and "real" space characters.
2213 */
2214 return 0;
2215 }
2216
2217 if (sss->typid == BPCHAROID)
2218 {
2219 /* Get true number of bytes, ignoring trailing spaces */
2220 len1 = bpchartruelen(a1p, len1);
2221 len2 = bpchartruelen(a2p, len2);
2222 }
2223
2224 if (len1 >= sss->buflen1)
2225 {
2226 sss->buflen1 = Max(len1 + 1, Min(sss->buflen1 * 2, MaxAllocSize));
2227 sss->buf1 = repalloc(sss->buf1, sss->buflen1);
2228 }
2229 if (len2 >= sss->buflen2)
2230 {
2231 sss->buflen2 = Max(len2 + 1, Min(sss->buflen2 * 2, MaxAllocSize));
2232 sss->buf2 = repalloc(sss->buf2, sss->buflen2);
2233 }
2234
2235 /*
2236 * We're likely to be asked to compare the same strings repeatedly, and
2237 * memcmp() is so much cheaper than strcoll() that it pays to try to cache
2238 * comparisons, even though in general there is no reason to think that
2239 * that will work out (every string datum may be unique). Caching does
2240 * not slow things down measurably when it doesn't work out, and can speed
2241 * things up by rather a lot when it does. In part, this is because the
2242 * memcmp() compares data from cachelines that are needed in L1 cache even
2243 * when the last comparison's result cannot be reused.
2244 */
2245 arg1_match = true;
2246 if (len1 != sss->last_len1 || memcmp(sss->buf1, a1p, len1) != 0)
2247 {
2248 arg1_match = false;
2249 memcpy(sss->buf1, a1p, len1);
2250 sss->buf1[len1] = '\0';
2251 sss->last_len1 = len1;
2252 }
2253
2254 /*
2255 * If we're comparing the same two strings as last time, we can return the
2256 * same answer without calling strcoll() again. This is more likely than
2257 * it seems (at least with moderate to low cardinality sets), because
2258 * quicksort compares the same pivot against many values.
2259 */
2260 if (len2 != sss->last_len2 || memcmp(sss->buf2, a2p, len2) != 0)
2261 {
2262 memcpy(sss->buf2, a2p, len2);
2263 sss->buf2[len2] = '\0';
2264 sss->last_len2 = len2;
2265 }
2266 else if (arg1_match && !sss->cache_blob)
2267 {
2268 /* Use result cached following last actual strcoll() call */
2269 return sss->last_returned;
2270 }
2271
2272 result = pg_strcoll(sss->buf1, sss->buf2, sss->locale);
2273
2274 /* Break tie if necessary. */
2275 if (result == 0 && sss->locale->deterministic)
2276 result = strcmp(sss->buf1, sss->buf2);
2277
2278 /* Cache result, perhaps saving an expensive strcoll() call next time */
2279 sss->cache_blob = false;
2280 sss->last_returned = result;
2281 return result;
2282}
int pg_strcoll(const char *arg1, const char *arg2, pg_locale_t locale)
Definition: pg_locale.c:1336

References bpchartruelen(), VarStringSortSupport::buf1, VarStringSortSupport::buf2, VarStringSortSupport::buflen1, VarStringSortSupport::buflen2, VarStringSortSupport::cache_blob, pg_locale_struct::deterministic, if(), VarStringSortSupport::last_len1, VarStringSortSupport::last_len2, VarStringSortSupport::last_returned, VarStringSortSupport::locale, Max, MaxAllocSize, Min, pg_strcoll(), repalloc(), SortSupportData::ssup_extra, and VarStringSortSupport::typid.

Referenced by namefastcmp_locale(), and varlenafastcmp_locale().

Variable Documentation

◆ bytea_output

int bytea_output = BYTEA_OUTPUT_HEX

Definition at line 48 of file varlena.c.

Referenced by byteaout().