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 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 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 5710 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 6250 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 5708 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 4191 of file varlena.c.

4194{
4195 const char *p = VARDATA_ANY(replace_text);
4196 const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4197
4198 while (p < p_end)
4199 {
4200 const char *chunk_start = p;
4201 int so;
4202 int eo;
4203
4204 /* Find next escape char, if any. */
4205 p = memchr(p, '\\', p_end - p);
4206 if (p == NULL)
4207 p = p_end;
4208
4209 /* Copy the text we just scanned over, if any. */
4210 if (p > chunk_start)
4211 appendBinaryStringInfo(str, chunk_start, p - chunk_start);
4212
4213 /* Done if at end of string, else advance over escape char. */
4214 if (p >= p_end)
4215 break;
4216 p++;
4217
4218 if (p >= p_end)
4219 {
4220 /* Escape at very end of input. Treat same as unexpected char */
4222 break;
4223 }
4224
4225 if (*p >= '1' && *p <= '9')
4226 {
4227 /* Use the back reference of regexp. */
4228 int idx = *p - '0';
4229
4230 so = pmatch[idx].rm_so;
4231 eo = pmatch[idx].rm_eo;
4232 p++;
4233 }
4234 else if (*p == '&')
4235 {
4236 /* Use the entire matched string. */
4237 so = pmatch[0].rm_so;
4238 eo = pmatch[0].rm_eo;
4239 p++;
4240 }
4241 else if (*p == '\\')
4242 {
4243 /* \\ means transfer one \ to output. */
4245 p++;
4246 continue;
4247 }
4248 else
4249 {
4250 /*
4251 * If escape char is not followed by any expected char, just treat
4252 * it as ordinary data to copy. (XXX would it be better to throw
4253 * an error?)
4254 */
4256 continue;
4257 }
4258
4259 if (so >= 0 && eo >= 0)
4260 {
4261 /*
4262 * Copy the text that is back reference of regexp. Note so and eo
4263 * are counted in characters not bytes.
4264 */
4265 char *chunk_start;
4266 int chunk_len;
4267
4268 Assert(so >= data_pos);
4269 chunk_start = start_ptr;
4270 chunk_start += charlen_to_bytelen(chunk_start, so - data_pos);
4271 chunk_len = charlen_to_bytelen(chunk_start, eo - so);
4272 appendBinaryStringInfo(str, chunk_start, chunk_len);
4273 }
4274 }
4275}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
#define Assert(condition)
Definition: c.h:815
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:4081

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

4852{
4854 char *fldsep = text_to_cstring(PG_GETARG_TEXT_PP(1));
4855
4856 PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, NULL));
4857}
#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:4893
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 4893 of file varlena.c.

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

4868{
4869 ArrayType *v;
4870 char *fldsep;
4871 char *null_string;
4872
4873 /* returns NULL when first or second parameter is NULL */
4874 if (PG_ARGISNULL(0) || PG_ARGISNULL(1))
4876
4877 v = PG_GETARG_ARRAYTYPE_P(0);
4879
4880 /* NULL null string is passed through as a null pointer */
4881 if (!PG_ARGISNULL(2))
4882 null_string = text_to_cstring(PG_GETARG_TEXT_PP(2));
4883 else
4884 null_string = NULL;
4885
4886 PG_RETURN_TEXT_P(array_to_text_internal(fcinfo, v, fldsep, null_string));
4887}
#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:961
#define DatumGetBpCharPP(X)
Definition: fmgr.h:293
int y
Definition: isn.c:71
int x
Definition: isn.c:70
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:703
int32_t int32
Definition: c.h:484
#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:698
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:1332
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 5469 of file varlena.c.

5470{
5471 FmgrInfo *foutcache;
5472 int i;
5473
5474 /* We keep the info in fn_mcxt so it survives across calls */
5475 foutcache = (FmgrInfo *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5476 PG_NARGS() * sizeof(FmgrInfo));
5477
5478 for (i = argidx; i < PG_NARGS(); i++)
5479 {
5480 Oid valtype;
5481 Oid typOutput;
5482 bool typIsVarlena;
5483
5484 valtype = get_fn_expr_argtype(fcinfo->flinfo, i);
5485 if (!OidIsValid(valtype))
5486 elog(ERROR, "could not determine data type of concat() input");
5487
5488 getTypeOutputInfo(valtype, &typOutput, &typIsVarlena);
5489 fmgr_info_cxt(typOutput, &foutcache[i], fcinfo->flinfo->fn_mcxt);
5490 }
5491
5492 fcinfo->flinfo->fn_extra = foutcache;
5493
5494 return foutcache;
5495}
#define OidIsValid(objectId)
Definition: c.h:732
#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:2934
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:337

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:649
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_larger()

Datum bytea_larger ( PG_FUNCTION_ARGS  )

Definition at line 4007 of file varlena.c.

4008{
4009 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4010 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4011 bytea *result;
4012 int len1,
4013 len2;
4014 int cmp;
4015
4016 len1 = VARSIZE_ANY_EXHDR(arg1);
4017 len2 = VARSIZE_ANY_EXHDR(arg2);
4018
4019 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4020 result = ((cmp > 0) || ((cmp == 0) && (len1 > len2)) ? arg1 : arg2);
4021
4022 PG_RETURN_BYTEA_P(result);
4023}
#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}
#define ereport(elevel,...)
Definition: elog.h:149
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_smaller()

Datum bytea_smaller ( PG_FUNCTION_ARGS  )

Definition at line 4026 of file varlena.c.

4027{
4028 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
4029 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
4030 bytea *result;
4031 int len1,
4032 len2;
4033 int cmp;
4034
4035 len1 = VARSIZE_ANY_EXHDR(arg1);
4036 len2 = VARSIZE_ANY_EXHDR(arg2);
4037
4038 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
4039 result = ((cmp < 0) || ((cmp == 0) && (len1 < len2)) ? arg1 : arg2);
4040
4041 PG_RETURN_BYTEA_P(result);
4042}

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

4046{
4048 MemoryContext oldcontext;
4049
4050 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
4051
4052 /* Use generic string SortSupport, forcing "C" collation */
4053 varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID);
4054
4055 MemoryContextSwitchTo(oldcontext);
4056
4058}

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:4544
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:5247

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:955
#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 3985 of file varlena.c.

3986{
3987 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3988 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3989 int len1,
3990 len2;
3991 int cmp;
3992
3993 len1 = VARSIZE_ANY_EXHDR(arg1);
3994 len2 = VARSIZE_ANY_EXHDR(arg2);
3995
3996 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3997 if ((cmp == 0) && (len1 != len2))
3998 cmp = (len1 < len2) ? -1 : 1;
3999
4000 PG_FREE_IF_COPY(arg1, 0);
4001 PG_FREE_IF_COPY(arg2, 1);
4002
4004}

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

3842{
3843 Datum arg1 = PG_GETARG_DATUM(0);
3844 Datum arg2 = PG_GETARG_DATUM(1);
3845 bool result;
3846 Size len1,
3847 len2;
3848
3849 /*
3850 * We can use a fast path for unequal lengths, which might save us from
3851 * having to detoast one or both values.
3852 */
3853 len1 = toast_raw_datum_size(arg1);
3854 len2 = toast_raw_datum_size(arg2);
3855 if (len1 != len2)
3856 result = false;
3857 else
3858 {
3859 bytea *barg1 = DatumGetByteaPP(arg1);
3860 bytea *barg2 = DatumGetByteaPP(arg2);
3861
3862 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3863 len1 - VARHDRSZ) == 0);
3864
3865 PG_FREE_IF_COPY(barg1, 0);
3866 PG_FREE_IF_COPY(barg2, 1);
3867 }
3868
3869 PG_RETURN_BOOL(result);
3870}
size_t Size
Definition: c.h:562
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 3965 of file varlena.c.

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

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:485
#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 3945 of file varlena.c.

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

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:129
#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 3925 of file varlena.c.

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

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

3906{
3907 bytea *arg1 = PG_GETARG_BYTEA_PP(0);
3908 bytea *arg2 = PG_GETARG_BYTEA_PP(1);
3909 int len1,
3910 len2;
3911 int cmp;
3912
3913 len1 = VARSIZE_ANY_EXHDR(arg1);
3914 len2 = VARSIZE_ANY_EXHDR(arg2);
3915
3916 cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
3917
3918 PG_FREE_IF_COPY(arg1, 0);
3919 PG_FREE_IF_COPY(arg2, 1);
3920
3921 PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));
3922}

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

3874{
3875 Datum arg1 = PG_GETARG_DATUM(0);
3876 Datum arg2 = PG_GETARG_DATUM(1);
3877 bool result;
3878 Size len1,
3879 len2;
3880
3881 /*
3882 * We can use a fast path for unequal lengths, which might save us from
3883 * having to detoast one or both values.
3884 */
3885 len1 = toast_raw_datum_size(arg1);
3886 len2 = toast_raw_datum_size(arg2);
3887 if (len1 != len2)
3888 result = true;
3889 else
3890 {
3891 bytea *barg1 = DatumGetByteaPP(arg1);
3892 bytea *barg2 = DatumGetByteaPP(arg2);
3893
3894 result = (memcmp(VARDATA_ANY(barg1), VARDATA_ANY(barg2),
3895 len1 - VARHDRSZ) != 0);
3896
3897 PG_FREE_IF_COPY(barg1, 0);
3898 PG_FREE_IF_COPY(barg2, 1);
3899 }
3900
3901 PG_RETURN_BOOL(result);
3902}

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
uint64_t uint64
Definition: c.h:489
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 p2, 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{
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
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, res, VARDATA, VARHDRSZ, and VARSIZE.

◆ byteaSetByte()

Datum byteaSetByte ( PG_FUNCTION_ARGS  )

Definition at line 3323 of file varlena.c.

3324{
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
3344}

References ereport, errcode(), errmsg(), ERROR, len, PG_GETARG_BYTEA_P_COPY, PG_GETARG_INT32, PG_RETURN_BYTEA_P, res, 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 4158 of file varlena.c.

4159{
4160 int result = 0;
4161 const char *p = VARDATA_ANY(replace_text);
4162 const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
4163
4164 while (p < p_end)
4165 {
4166 /* Find next escape char, if any. */
4167 p = memchr(p, '\\', p_end - p);
4168 if (p == NULL)
4169 break;
4170 p++;
4171 /* Note: a backslash at the end doesn't require extra processing. */
4172 if (p < p_end)
4173 {
4174 if (*p >= '1' && *p <= '9')
4175 return 2; /* Found a submatch specifier, so done */
4176 result = 1; /* Found some other sequence, keep looking */
4177 p++;
4178 }
4179 }
4180 return result;
4181}

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

5509{
5510 text *result;
5512 FmgrInfo *foutcache;
5513 bool first_arg = true;
5514 int i;
5515
5516 /*
5517 * concat(VARIADIC some-array) is essentially equivalent to
5518 * array_to_text(), ie concat the array elements with the given separator.
5519 * So we just pass the case off to that code.
5520 */
5521 if (get_fn_expr_variadic(fcinfo->flinfo))
5522 {
5523 ArrayType *arr;
5524
5525 /* Should have just the one argument */
5526 Assert(argidx == PG_NARGS() - 1);
5527
5528 /* concat(VARIADIC NULL) is defined as NULL */
5529 if (PG_ARGISNULL(argidx))
5530 return NULL;
5531
5532 /*
5533 * Non-null argument had better be an array. We assume that any call
5534 * context that could let get_fn_expr_variadic return true will have
5535 * checked that a VARIADIC-labeled parameter actually is an array. So
5536 * it should be okay to just Assert that it's an array rather than
5537 * doing a full-fledged error check.
5538 */
5540
5541 /* OK, safe to fetch the array value */
5542 arr = PG_GETARG_ARRAYTYPE_P(argidx);
5543
5544 /*
5545 * And serialize the array. We tell array_to_text to ignore null
5546 * elements, which matches the behavior of the loop below.
5547 */
5548 return array_to_text_internal(fcinfo, arr, sepstr, NULL);
5549 }
5550
5551 /* Normal case without explicit VARIADIC marker */
5553
5554 /* Get output function info, building it if first time through */
5555 foutcache = (FmgrInfo *) fcinfo->flinfo->fn_extra;
5556 if (foutcache == NULL)
5557 foutcache = build_concat_foutcache(fcinfo, argidx);
5558
5559 for (i = argidx; i < PG_NARGS(); i++)
5560 {
5561 if (!PG_ARGISNULL(i))
5562 {
5564
5565 /* add separator if appropriate */
5566 if (first_arg)
5567 first_arg = false;
5568 else
5569 appendStringInfoString(&str, sepstr);
5570
5571 /* call the appropriate type output function, append the result */
5573 OutputFunctionCall(&foutcache[i], value));
5574 }
5575 }
5576
5577 result = cstring_to_text_with_len(str.data, str.len);
5578 pfree(str.data);
5579
5580 return result;
5581}
bool get_fn_expr_variadic(FmgrInfo *flinfo)
Definition: fmgr.c:2044
Oid get_base_element_type(Oid typid)
Definition: lsyscache.c:2859
static FmgrInfo * build_concat_foutcache(FunctionCallInfo fcinfo, int argidx)
Definition: varlena.c:5469

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

5016{
5017 const char *digits = "0123456789abcdef";
5018
5019 /* We size the buffer for to_bin's longest possible return value. */
5020 char buf[sizeof(uint64) * BITS_PER_BYTE];
5021 char *const end = buf + sizeof(buf);
5022 char *ptr = end;
5023
5024 Assert(base > 1);
5025 Assert(base <= 16);
5026
5027 do
5028 {
5029 *--ptr = digits[value % base];
5030 value /= base;
5031 } while (ptr > buf && value);
5032
5033 return cstring_to_text_with_len(ptr, end - ptr);
5034}
int digits
Definition: informix.c:691
#define BITS_PER_BYTE

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

6329{
6330 Assert(state);
6331
6332 return state->match;
6333}

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

6558{
6559 if (c >= '0' && c <= '9')
6560 return c - '0';
6561 if (c >= 'a' && c <= 'f')
6562 return c - 'a' + 0xA;
6563 if (c >= 'A' && c <= 'F')
6564 return c - 'A' + 0xA;
6565 elog(ERROR, "invalid hexadecimal digit");
6566 return 0; /* not reached */
6567}
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 6573 of file varlena.c.

6574{
6575 unsigned int result = 0;
6576
6577 for (size_t i = 0; i < n; i++)
6578 result += hexval(instr[i]) << (4 * (n - i - 1));
6579
6580 return result;
6581}
static unsigned int hexval(unsigned char c)
Definition: varlena.c:6557

References hexval(), and i.

Referenced by unistr().

◆ icu_unicode_version()

Datum icu_unicode_version ( PG_FUNCTION_ARGS  )

Definition at line 6387 of file varlena.c.

6388{
6389#ifdef USE_ICU
6390 PG_RETURN_TEXT_P(cstring_to_text(U_UNICODE_VERSION));
6391#else
6393#endif
6394}
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 6273 of file varlena.c.

6274{
6275 Assert(state);
6276 Assert(max_d >= 0);
6277
6278 state->source = source;
6279 state->min_d = -1;
6280 state->max_d = max_d;
6281 state->match = NULL;
6282}
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().

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

6548{
6549 for (size_t i = 0; i < n; i++)
6550 if (!isxdigit((unsigned char) instr[i]))
6551 return false;
6552
6553 return true;
6554}

References i.

Referenced by unistr().

◆ makeStringAggState()

static StringInfo makeStringAggState ( FunctionCallInfo  fcinfo)
static

Definition at line 5247 of file varlena.c.

5248{
5250 MemoryContext aggcontext;
5251 MemoryContext oldcontext;
5252
5253 if (!AggCheckCallContext(fcinfo, &aggcontext))
5254 {
5255 /* cannot be called directly because of internal-type argument */
5256 elog(ERROR, "string_agg_transfn called in non-aggregate context");
5257 }
5258
5259 /*
5260 * Create state in aggregate context. It'll stay there across subsequent
5261 * calls.
5262 */
5263 oldcontext = MemoryContextSwitchTo(aggcontext);
5265 MemoryContextSwitchTo(oldcontext);
5266
5267 return state;
5268}
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 3429 of file varlena.c.

3430{
3431 Name s = PG_GETARG_NAME(0);
3432
3434}

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

5147{
5148 int typlen;
5149 char *result;
5150 ToastCompressionId cmid;
5151
5152 /* On first call, get the input type's typlen, and save at *fn_extra */
5153 if (fcinfo->flinfo->fn_extra == NULL)
5154 {
5155 /* Lookup the datatype of the supplied argument */
5156 Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5157
5158 typlen = get_typlen(argtypeid);
5159 if (typlen == 0) /* should not happen */
5160 elog(ERROR, "cache lookup failed for type %u", argtypeid);
5161
5162 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5163 sizeof(int));
5164 *((int *) fcinfo->flinfo->fn_extra) = typlen;
5165 }
5166 else
5167 typlen = *((int *) fcinfo->flinfo->fn_extra);
5168
5169 if (typlen != -1)
5171
5172 /* get the compression method id stored in the compressed varlena */
5173 cmid = toast_get_compression_id((struct varlena *)
5175 if (cmid == TOAST_INVALID_COMPRESSION_ID)
5177
5178 /* convert compression method id to compression method name */
5179 switch (cmid)
5180 {
5182 result = "pglz";
5183 break;
5185 result = "lz4";
5186 break;
5187 default:
5188 elog(ERROR, "invalid compression method id %d", cmid);
5189 }
5190
5192}
int16 get_typlen(Oid typid)
Definition: lsyscache.c:2224
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 5099 of file varlena.c.

5100{
5102 int32 result;
5103 int typlen;
5104
5105 /* On first call, get the input type's typlen, and save at *fn_extra */
5106 if (fcinfo->flinfo->fn_extra == NULL)
5107 {
5108 /* Lookup the datatype of the supplied argument */
5109 Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5110
5111 typlen = get_typlen(argtypeid);
5112 if (typlen == 0) /* should not happen */
5113 elog(ERROR, "cache lookup failed for type %u", argtypeid);
5114
5115 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5116 sizeof(int));
5117 *((int *) fcinfo->flinfo->fn_extra) = typlen;
5118 }
5119 else
5120 typlen = *((int *) fcinfo->flinfo->fn_extra);
5121
5122 if (typlen == -1)
5123 {
5124 /* varlena type, possibly toasted */
5125 result = toast_datum_size(value);
5126 }
5127 else if (typlen == -2)
5128 {
5129 /* cstring */
5130 result = strlen(DatumGetCString(value)) + 1;
5131 }
5132 else
5133 {
5134 /* ordinary fixed-width type */
5135 result = typlen;
5136 }
5137
5138 PG_RETURN_INT32(result);
5139}
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 5199 of file varlena.c.

5200{
5201 int typlen;
5202 struct varlena *attr;
5203 struct varatt_external toast_pointer;
5204
5205 /* On first call, get the input type's typlen, and save at *fn_extra */
5206 if (fcinfo->flinfo->fn_extra == NULL)
5207 {
5208 /* Lookup the datatype of the supplied argument */
5209 Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
5210
5211 typlen = get_typlen(argtypeid);
5212 if (typlen == 0) /* should not happen */
5213 elog(ERROR, "cache lookup failed for type %u", argtypeid);
5214
5215 fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
5216 sizeof(int));
5217 *((int *) fcinfo->flinfo->fn_extra) = typlen;
5218 }
5219 else
5220 typlen = *((int *) fcinfo->flinfo->fn_extra);
5221
5222 if (typlen != -1)
5224
5225 attr = (struct varlena *) DatumGetPointer(PG_GETARG_DATUM(0));
5226
5227 if (!VARATT_IS_EXTERNAL_ONDISK(attr))
5229
5230 VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr);
5231
5232 PG_RETURN_OID(toast_pointer.va_valueid);
5233}
#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 4081 of file varlena.c.

4082{
4083 text *src_text = PG_GETARG_TEXT_PP(0);
4084 text *from_sub_text = PG_GETARG_TEXT_PP(1);
4085 text *to_sub_text = PG_GETARG_TEXT_PP(2);
4086 int src_text_len;
4087 int from_sub_text_len;
4089 text *ret_text;
4090 int chunk_len;
4091 char *curr_ptr;
4092 char *start_ptr;
4094 bool found;
4095
4096 src_text_len = VARSIZE_ANY_EXHDR(src_text);
4097 from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text);
4098
4099 /* Return unmodified source string if empty source or pattern */
4100 if (src_text_len < 1 || from_sub_text_len < 1)
4101 {
4102 PG_RETURN_TEXT_P(src_text);
4103 }
4104
4105 text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state);
4106
4107 found = text_position_next(&state);
4108
4109 /* When the from_sub_text is not found, there is nothing to do. */
4110 if (!found)
4111 {
4113 PG_RETURN_TEXT_P(src_text);
4114 }
4116 start_ptr = VARDATA_ANY(src_text);
4117
4119
4120 do
4121 {
4123
4124 /* copy the data skipped over by last text_position_next() */
4125 chunk_len = curr_ptr - start_ptr;
4126 appendBinaryStringInfo(&str, start_ptr, chunk_len);
4127
4128 appendStringInfoText(&str, to_sub_text);
4129
4130 start_ptr = curr_ptr + state.last_match_len;
4131
4132 found = text_position_next(&state);
4133 if (found)
4135 }
4136 while (found);
4137
4138 /* copy trailing data */
4139 chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4140 appendBinaryStringInfo(&str, start_ptr, chunk_len);
4141
4143
4144 ret_text = cstring_to_text_with_len(str.data, str.len);
4145 pfree(str.data);
4146
4147 PG_RETURN_TEXT_P(ret_text);
4148}
#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:4067
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 4291 of file varlena.c.

4295{
4296 text *ret_text;
4297 regex_t *re;
4298 int src_text_len = VARSIZE_ANY_EXHDR(src_text);
4299 int nmatches = 0;
4301 regmatch_t pmatch[10]; /* main match, plus \1 to \9 */
4302 int nmatch = lengthof(pmatch);
4303 pg_wchar *data;
4304 size_t data_len;
4305 int data_pos;
4306 char *start_ptr;
4307 int escape_status;
4308
4310
4311 /* Convert data string to wide characters. */
4312 data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
4313 data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
4314
4315 /* Check whether replace_text has escapes, especially regexp submatches. */
4317
4318 /* If no regexp submatches, we can use REG_NOSUB. */
4319 if (escape_status < 2)
4320 {
4321 cflags |= REG_NOSUB;
4322 /* Also tell pg_regexec we only want the whole-match location. */
4323 nmatch = 1;
4324 }
4325
4326 /* Prepare the regexp. */
4327 re = RE_compile_and_cache(pattern_text, cflags, collation);
4328
4329 /* start_ptr points to the data_pos'th character of src_text */
4330 start_ptr = (char *) VARDATA_ANY(src_text);
4331 data_pos = 0;
4332
4333 while (search_start <= data_len)
4334 {
4335 int regexec_result;
4336
4338
4339 regexec_result = pg_regexec(re,
4340 data,
4341 data_len,
4342 search_start,
4343 NULL, /* no details */
4344 nmatch,
4345 pmatch,
4346 0);
4347
4348 if (regexec_result == REG_NOMATCH)
4349 break;
4350
4351 if (regexec_result != REG_OKAY)
4352 {
4353 char errMsg[100];
4354
4355 pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
4356 ereport(ERROR,
4357 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
4358 errmsg("regular expression failed: %s", errMsg)));
4359 }
4360
4361 /*
4362 * Count matches, and decide whether to replace this match.
4363 */
4364 nmatches++;
4365 if (n > 0 && nmatches != n)
4366 {
4367 /*
4368 * No, so advance search_start, but not start_ptr/data_pos. (Thus,
4369 * we treat the matched text as if it weren't matched, and copy it
4370 * to the output later.)
4371 */
4372 search_start = pmatch[0].rm_eo;
4373 if (pmatch[0].rm_so == pmatch[0].rm_eo)
4374 search_start++;
4375 continue;
4376 }
4377
4378 /*
4379 * Copy the text to the left of the match position. Note we are given
4380 * character not byte indexes.
4381 */
4382 if (pmatch[0].rm_so - data_pos > 0)
4383 {
4384 int chunk_len;
4385
4386 chunk_len = charlen_to_bytelen(start_ptr,
4387 pmatch[0].rm_so - data_pos);
4388 appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4389
4390 /*
4391 * Advance start_ptr over that text, to avoid multiple rescans of
4392 * it if the replace_text contains multiple back-references.
4393 */
4394 start_ptr += chunk_len;
4395 data_pos = pmatch[0].rm_so;
4396 }
4397
4398 /*
4399 * Copy the replace_text, processing escapes if any are present.
4400 */
4401 if (escape_status > 0)
4403 start_ptr, data_pos);
4404 else
4406
4407 /* Advance start_ptr and data_pos over the matched text. */
4408 start_ptr += charlen_to_bytelen(start_ptr,
4409 pmatch[0].rm_eo - data_pos);
4410 data_pos = pmatch[0].rm_eo;
4411
4412 /*
4413 * If we only want to replace one occurrence, we're done.
4414 */
4415 if (n > 0)
4416 break;
4417
4418 /*
4419 * Advance search position. Normally we start the next search at the
4420 * end of the previous match; but if the match was of zero length, we
4421 * have to advance by one character, or we'd just find the same match
4422 * again.
4423 */
4424 search_start = data_pos;
4425 if (pmatch[0].rm_so == pmatch[0].rm_eo)
4426 search_start++;
4427 }
4428
4429 /*
4430 * Copy the text to the right of the last match.
4431 */
4432 if (data_pos < data_len)
4433 {
4434 int chunk_len;
4435
4436 chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
4437 appendBinaryStringInfo(&buf, start_ptr, chunk_len);
4438 }
4439
4440 ret_text = cstring_to_text_with_len(buf.data, buf.len);
4441 pfree(buf.data);
4442 pfree(data);
4443
4444 return ret_text;
4445}
#define lengthof(array)
Definition: c.h:745
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:4158
static void appendStringInfoRegexpSubstr(StringInfo str, text *replace_text, regmatch_t *pmatch, char *start_ptr, int data_pos)
Definition: varlena.c:4191

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

6238{
6239 while (len > 0)
6240 {
6241 len--;
6242 if (s1[len] != s2[len])
6243 return false;
6244 }
6245 return true;
6246}

References len, s1, and s2.

Referenced by varstr_levenshtein().

◆ split_part()

Datum split_part ( PG_FUNCTION_ARGS  )

Definition at line 4453 of file varlena.c.

4454{
4455 text *inputstring = PG_GETARG_TEXT_PP(0);
4456 text *fldsep = PG_GETARG_TEXT_PP(1);
4457 int fldnum = PG_GETARG_INT32(2);
4458 int inputstring_len;
4459 int fldsep_len;
4461 char *start_ptr;
4462 char *end_ptr;
4463 text *result_text;
4464 bool found;
4465
4466 /* field number is 1 based */
4467 if (fldnum == 0)
4468 ereport(ERROR,
4469 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4470 errmsg("field position must not be zero")));
4471
4472 inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4473 fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4474
4475 /* return empty string for empty input string */
4476 if (inputstring_len < 1)
4478
4479 /* handle empty field separator */
4480 if (fldsep_len < 1)
4481 {
4482 /* if first or last field, return input string, else empty string */
4483 if (fldnum == 1 || fldnum == -1)
4484 PG_RETURN_TEXT_P(inputstring);
4485 else
4487 }
4488
4489 /* find the first field separator */
4490 text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state);
4491
4492 found = text_position_next(&state);
4493
4494 /* special case if fldsep not found at all */
4495 if (!found)
4496 {
4498 /* if first or last field, return input string, else empty string */
4499 if (fldnum == 1 || fldnum == -1)
4500 PG_RETURN_TEXT_P(inputstring);
4501 else
4503 }
4504
4505 /*
4506 * take care of a negative field number (i.e. count from the right) by
4507 * converting to a positive field number; we need total number of fields
4508 */
4509 if (fldnum < 0)
4510 {
4511 /* we found a fldsep, so there are at least two fields */
4512 int numfields = 2;
4513
4514 while (text_position_next(&state))
4515 numfields++;
4516
4517 /* special case of last field does not require an extra pass */
4518 if (fldnum == -1)
4519 {
4520 start_ptr = text_position_get_match_ptr(&state) + state.last_match_len;
4521 end_ptr = VARDATA_ANY(inputstring) + inputstring_len;
4524 end_ptr - start_ptr));
4525 }
4526
4527 /* else, convert fldnum to positive notation */
4528 fldnum += numfields + 1;
4529
4530 /* if nonexistent field, return empty string */
4531 if (fldnum <= 0)
4532 {
4535 }
4536
4537 /* reset to pointing at first match, but now with positive fldnum */
4539 found = text_position_next(&state);
4540 Assert(found);
4541 }
4542
4543 /* identify bounds of first field */
4544 start_ptr = VARDATA_ANY(inputstring);
4546
4547 while (found && --fldnum > 0)
4548 {
4549 /* identify bounds of next field */
4550 start_ptr = end_ptr + state.last_match_len;
4551 found = text_position_next(&state);
4552 if (found)
4554 }
4555
4557
4558 if (fldnum > 0)
4559 {
4560 /* N'th field separator not found */
4561 /* if last field requested, return it, else empty string */
4562 if (fldnum == 1)
4563 {
4564 int last_len = start_ptr - VARDATA_ANY(inputstring);
4565
4566 result_text = cstring_to_text_with_len(start_ptr,
4567 inputstring_len - last_len);
4568 }
4569 else
4570 result_text = cstring_to_text("");
4571 }
4572 else
4573 {
4574 /* non-last field requested */
4575 result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr);
4576 }
4577
4578 PG_RETURN_TEXT_P(result_text);
4579}
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 4676 of file varlena.c.

4677{
4678 text *inputstring;
4679 text *fldsep;
4680 text *null_string;
4681 Oid collation = PG_GET_COLLATION();
4682 int inputstring_len;
4683 int fldsep_len;
4684 char *start_ptr;
4685 text *result_text;
4686
4687 /* when input string is NULL, then result is NULL too */
4688 if (PG_ARGISNULL(0))
4689 return false;
4690
4691 inputstring = PG_GETARG_TEXT_PP(0);
4692
4693 /* fldsep can be NULL */
4694 if (!PG_ARGISNULL(1))
4695 fldsep = PG_GETARG_TEXT_PP(1);
4696 else
4697 fldsep = NULL;
4698
4699 /* null_string can be NULL or omitted */
4700 if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
4701 null_string = PG_GETARG_TEXT_PP(2);
4702 else
4703 null_string = NULL;
4704
4705 if (fldsep != NULL)
4706 {
4707 /*
4708 * Normal case with non-null fldsep. Use the text_position machinery
4709 * to search for occurrences of fldsep.
4710 */
4712
4713 inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4714 fldsep_len = VARSIZE_ANY_EXHDR(fldsep);
4715
4716 /* return empty set for empty input string */
4717 if (inputstring_len < 1)
4718 return true;
4719
4720 /* empty field separator: return input string as a one-element set */
4721 if (fldsep_len < 1)
4722 {
4723 split_text_accum_result(tstate, inputstring,
4724 null_string, collation);
4725 return true;
4726 }
4727
4728 text_position_setup(inputstring, fldsep, collation, &state);
4729
4730 start_ptr = VARDATA_ANY(inputstring);
4731
4732 for (;;)
4733 {
4734 bool found;
4735 char *end_ptr;
4736 int chunk_len;
4737
4739
4740 found = text_position_next(&state);
4741 if (!found)
4742 {
4743 /* fetch last field */
4744 chunk_len = ((char *) inputstring + VARSIZE_ANY(inputstring)) - start_ptr;
4745 end_ptr = NULL; /* not used, but some compilers complain */
4746 }
4747 else
4748 {
4749 /* fetch non-last field */
4751 chunk_len = end_ptr - start_ptr;
4752 }
4753
4754 /* build a temp text datum to pass to split_text_accum_result */
4755 result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4756
4757 /* stash away this field */
4758 split_text_accum_result(tstate, result_text,
4759 null_string, collation);
4760
4761 pfree(result_text);
4762
4763 if (!found)
4764 break;
4765
4766 start_ptr = end_ptr + state.last_match_len;
4767 }
4768
4770 }
4771 else
4772 {
4773 /*
4774 * When fldsep is NULL, each character in the input string becomes a
4775 * separate element in the result set. The separator is effectively
4776 * the space between characters.
4777 */
4778 inputstring_len = VARSIZE_ANY_EXHDR(inputstring);
4779
4780 start_ptr = VARDATA_ANY(inputstring);
4781
4782 while (inputstring_len > 0)
4783 {
4784 int chunk_len = pg_mblen(start_ptr);
4785
4787
4788 /* build a temp text datum to pass to split_text_accum_result */
4789 result_text = cstring_to_text_with_len(start_ptr, chunk_len);
4790
4791 /* stash away this field */
4792 split_text_accum_result(tstate, result_text,
4793 null_string, collation);
4794
4795 pfree(result_text);
4796
4797 start_ptr += chunk_len;
4798 inputstring_len -= chunk_len;
4799 }
4800 }
4801
4802 return true;
4803}
static void split_text_accum_result(SplitTextOutputData *tstate, text *field_value, text *null_string, Oid collation)
Definition: varlena.c:4812

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

4816{
4817 bool is_null = false;
4818
4819 if (null_string && text_isequal(field_value, null_string, collation))
4820 is_null = true;
4821
4822 if (tstate->tupstore)
4823 {
4824 Datum values[1];
4825 bool nulls[1];
4826
4827 values[0] = PointerGetDatum(field_value);
4828 nulls[0] = is_null;
4829
4831 tstate->tupdesc,
4832 values,
4833 nulls);
4834 }
4835 else
4836 {
4837 tstate->astate = accumArrayResult(tstate->astate,
4838 PointerGetDatum(field_value),
4839 is_null,
4840 TEXTOID,
4842 }
4843}
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:4585

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

3633{
3634 char *nextp = rawstring;
3635 bool done = false;
3636
3637 *namelist = NIL;
3638
3639 while (scanner_isspace(*nextp))
3640 nextp++; /* skip leading whitespace */
3641
3642 if (*nextp == '\0')
3643 return true; /* allow empty string */
3644
3645 /* At the top of the loop, we are at start of a new directory. */
3646 do
3647 {
3648 char *curname;
3649 char *endp;
3650
3651 if (*nextp == '"')
3652 {
3653 /* Quoted name --- collapse quote-quote pairs */
3654 curname = nextp + 1;
3655 for (;;)
3656 {
3657 endp = strchr(nextp + 1, '"');
3658 if (endp == NULL)
3659 return false; /* mismatched quotes */
3660 if (endp[1] != '"')
3661 break; /* found end of quoted name */
3662 /* Collapse adjacent quotes into one quote, and look again */
3663 memmove(endp, endp + 1, strlen(endp));
3664 nextp = endp;
3665 }
3666 /* endp now points at the terminating quote */
3667 nextp = endp + 1;
3668 }
3669 else
3670 {
3671 /* Unquoted name --- extends to separator or end of string */
3672 curname = endp = nextp;
3673 while (*nextp && *nextp != separator)
3674 {
3675 /* trailing whitespace should not be included in name */
3676 if (!scanner_isspace(*nextp))
3677 endp = nextp + 1;
3678 nextp++;
3679 }
3680 if (curname == endp)
3681 return false; /* empty unquoted name not allowed */
3682 }
3683
3684 while (scanner_isspace(*nextp))
3685 nextp++; /* skip trailing whitespace */
3686
3687 if (*nextp == separator)
3688 {
3689 nextp++;
3690 while (scanner_isspace(*nextp))
3691 nextp++; /* skip leading whitespace for next */
3692 /* we expect another name, so done remains false */
3693 }
3694 else if (*nextp == '\0')
3695 done = true;
3696 else
3697 return false; /* invalid syntax */
3698
3699 /* Now safe to overwrite separator with a null */
3700 *endp = '\0';
3701
3702 /* Truncate path if it's overlength */
3703 if (strlen(curname) >= MAXPGPATH)
3704 curname[MAXPGPATH - 1] = '\0';
3705
3706 /*
3707 * Finished isolating current name --- add it to list
3708 */
3709 curname = pstrdup(curname);
3710 canonicalize_path(curname);
3711 *namelist = lappend(*namelist, curname);
3712
3713 /* Loop back if we didn't reach end of string */
3714 } while (!done);
3715
3716 return true;
3717}
List * lappend(List *list, void *datum)
Definition: list.c:339
char * pstrdup(const char *in)
Definition: mcxt.c:1696
#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 3752 of file varlena.c.

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

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

3506{
3507 char *nextp = rawstring;
3508 bool done = false;
3509
3510 *namelist = NIL;
3511
3512 while (scanner_isspace(*nextp))
3513 nextp++; /* skip leading whitespace */
3514
3515 if (*nextp == '\0')
3516 return true; /* allow empty string */
3517
3518 /* At the top of the loop, we are at start of a new identifier. */
3519 do
3520 {
3521 char *curname;
3522 char *endp;
3523
3524 if (*nextp == '"')
3525 {
3526 /* Quoted name --- collapse quote-quote pairs, no downcasing */
3527 curname = nextp + 1;
3528 for (;;)
3529 {
3530 endp = strchr(nextp + 1, '"');
3531 if (endp == NULL)
3532 return false; /* mismatched quotes */
3533 if (endp[1] != '"')
3534 break; /* found end of quoted name */
3535 /* Collapse adjacent quotes into one quote, and look again */
3536 memmove(endp, endp + 1, strlen(endp));
3537 nextp = endp;
3538 }
3539 /* endp now points at the terminating quote */
3540 nextp = endp + 1;
3541 }
3542 else
3543 {
3544 /* Unquoted name --- extends to separator or whitespace */
3545 char *downname;
3546 int len;
3547
3548 curname = nextp;
3549 while (*nextp && *nextp != separator &&
3550 !scanner_isspace(*nextp))
3551 nextp++;
3552 endp = nextp;
3553 if (curname == nextp)
3554 return false; /* empty unquoted name not allowed */
3555
3556 /*
3557 * Downcase the identifier, using same code as main lexer does.
3558 *
3559 * XXX because we want to overwrite the input in-place, we cannot
3560 * support a downcasing transformation that increases the string
3561 * length. This is not a problem given the current implementation
3562 * of downcase_truncate_identifier, but we'll probably have to do
3563 * something about this someday.
3564 */
3565 len = endp - curname;
3566 downname = downcase_truncate_identifier(curname, len, false);
3567 Assert(strlen(downname) <= len);
3568 strncpy(curname, downname, len); /* strncpy is required here */
3569 pfree(downname);
3570 }
3571
3572 while (scanner_isspace(*nextp))
3573 nextp++; /* skip trailing whitespace */
3574
3575 if (*nextp == separator)
3576 {
3577 nextp++;
3578 while (scanner_isspace(*nextp))
3579 nextp++; /* skip leading whitespace for next */
3580 /* we expect another name, so done remains false */
3581 }
3582 else if (*nextp == '\0')
3583 done = true;
3584 else
3585 return false; /* invalid syntax */
3586
3587 /* Now safe to overwrite separator with a null */
3588 *endp = '\0';
3589
3590 /* Truncate name if it's overlength */
3591 truncate_identifier(curname, strlen(curname), false);
3592
3593 /*
3594 * Finished isolating current name --- add it to list
3595 */
3596 *namelist = lappend(*namelist, curname);
3597
3598 /* Loop back if we didn't reach end of string */
3599 } while (!done);
3600
3601 return true;
3602}
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_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 5326 of file varlena.c.

5327{
5328 StringInfo state1;
5329 StringInfo state2;
5330 MemoryContext agg_context;
5331
5332 if (!AggCheckCallContext(fcinfo, &agg_context))
5333 elog(ERROR, "aggregate function called in non-aggregate context");
5334
5335 state1 = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0);
5336 state2 = PG_ARGISNULL(1) ? NULL : (StringInfo) PG_GETARG_POINTER(1);
5337
5338 if (state2 == NULL)
5339 {
5340 /*
5341 * NULL state2 is easy, just return state1, which we know is already
5342 * in the agg_context
5343 */
5344 if (state1 == NULL)
5346 PG_RETURN_POINTER(state1);
5347 }
5348
5349 if (state1 == NULL)
5350 {
5351 /* We must copy state2's data into the agg_context */
5352 MemoryContext old_context;
5353
5354 old_context = MemoryContextSwitchTo(agg_context);
5355 state1 = makeStringAggState(fcinfo);
5356 appendBinaryStringInfo(state1, state2->data, state2->len);
5357 state1->cursor = state2->cursor;
5358 MemoryContextSwitchTo(old_context);
5359 }
5360 else if (state2->len > 0)
5361 {
5362 /* Combine ... state1->cursor does not change in this case */
5363 appendBinaryStringInfo(state1, state2->data, state2->len);
5364 }
5365
5366 PG_RETURN_POINTER(state1);
5367}

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

5408{
5409 bytea *sstate;
5410 StringInfo result;
5412 char *data;
5413 int datalen;
5414
5415 /* cannot be called directly because of internal-type argument */
5416 Assert(AggCheckCallContext(fcinfo, NULL));
5417
5418 sstate = PG_GETARG_BYTEA_PP(0);
5419
5420 /*
5421 * Initialize a StringInfo so that we can "receive" it using the standard
5422 * recv-function infrastructure.
5423 */
5425 VARSIZE_ANY_EXHDR(sstate));
5426
5427 result = makeStringAggState(fcinfo);
5428
5429 /* cursor */
5430 result->cursor = pq_getmsgint(&buf, 4);
5431
5432 /* data */
5433 datalen = VARSIZE_ANY_EXHDR(sstate) - 4;
5434 data = (char *) pq_getmsgbytes(&buf, datalen);
5435 appendBinaryStringInfo(result, data, datalen);
5436
5437 pq_getmsgend(&buf);
5438
5439 PG_RETURN_POINTER(result);
5440}
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 5443 of file varlena.c.

5444{
5446
5447 /* cannot be called directly because of internal-type argument */
5448 Assert(AggCheckCallContext(fcinfo, NULL));
5449
5451
5452 if (state != NULL)
5453 {
5454 /* As per comment in transfn, strip data before the cursor position */
5456 state->len - state->cursor));
5457 }
5458 else
5460}

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

5377{
5380 bytea *result;
5381
5382 /* cannot be called directly because of internal-type argument */
5383 Assert(AggCheckCallContext(fcinfo, NULL));
5384
5386
5388
5389 /* cursor */
5390 pq_sendint(&buf, state->cursor, 4);
5391
5392 /* data */
5393 pq_sendbytes(&buf, state->data, state->len);
5394
5395 result = pq_endtypsend(&buf);
5396
5397 PG_RETURN_BYTEA_P(result);
5398}
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 5271 of file varlena.c.

5272{
5274
5276
5277 /* Append the value unless null, preceding it with the delimiter. */
5278 if (!PG_ARGISNULL(1))
5279 {
5281 bool isfirst = false;
5282
5283 /*
5284 * You might think we can just throw away the first delimiter, however
5285 * we must keep it as we may be a parallel worker doing partial
5286 * aggregation building a state to send to the main process. We need
5287 * to keep the delimiter of every aggregation so that the combine
5288 * function can properly join up the strings of two separately
5289 * partially aggregated results. The first delimiter is only stripped
5290 * off in the final function. To know how much to strip off the front
5291 * of the string, we store the length of the first delimiter in the
5292 * StringInfo's cursor field, which we don't otherwise need here.
5293 */
5294 if (state == NULL)
5295 {
5296 state = makeStringAggState(fcinfo);
5297 isfirst = true;
5298 }
5299
5300 if (!PG_ARGISNULL(2))
5301 {
5302 text *delim = PG_GETARG_TEXT_PP(2);
5303
5305 if (isfirst)
5306 state->cursor = VARSIZE_ANY_EXHDR(delim);
5307 }
5308
5310 }
5311
5312 /*
5313 * The transition type for string_agg() is declared to be "internal",
5314 * which is a pass-by-value type the same size as a pointer.
5315 */
5316 if (state)
5319}

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

5588{
5589 text *result;
5590
5591 result = concat_internal("", 0, fcinfo);
5592 if (result == NULL)
5594 PG_RETURN_TEXT_P(result);
5595}
static text * concat_internal(const char *sepstr, int argidx, FunctionCallInfo fcinfo)
Definition: varlena.c:5507

References concat_internal(), PG_RETURN_NULL, and PG_RETURN_TEXT_P.

◆ text_concat_ws()

Datum text_concat_ws ( PG_FUNCTION_ARGS  )

Definition at line 5602 of file varlena.c.

5603{
5604 char *sep;
5605 text *result;
5606
5607 /* return NULL when separator is NULL */
5608 if (PG_ARGISNULL(0))
5611
5612 result = concat_internal(sep, 1, fcinfo);
5613 if (result == NULL)
5615 PG_RETURN_TEXT_P(result);
5616}

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

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

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(), fmt, 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 6175 of file varlena.c.

6177{
6178 bool align_to_left = false;
6179 int len;
6180
6181 /* fast path for typical easy case */
6182 if (width == 0)
6183 {
6185 return;
6186 }
6187
6188 if (width < 0)
6189 {
6190 /* Negative width: implicit '-' flag, then take absolute value */
6191 align_to_left = true;
6192 /* -INT_MIN is undefined */
6193 if (width <= INT_MIN)
6194 ereport(ERROR,
6195 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6196 errmsg("number is out of range")));
6197 width = -width;
6198 }
6199 else if (flags & TEXT_FORMAT_FLAG_MINUS)
6200 align_to_left = true;
6201
6202 len = pg_mbstrlen(str);
6203 if (align_to_left)
6204 {
6205 /* left justify */
6207 if (len < width)
6208 appendStringInfoSpaces(buf, width - len);
6209 }
6210 else
6211 {
6212 /* right justify */
6213 if (len < width)
6214 appendStringInfoSpaces(buf, width - len);
6216 }
6217}
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:5708

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

6228{
6229 return text_format(fcinfo);
6230}
Datum text_format(PG_FUNCTION_ARGS)
Definition: varlena.c:5723

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

6001{
6002 bool found = false;
6003 const char *cp = *ptr;
6004 int val = 0;
6005
6006 while (*cp >= '0' && *cp <= '9')
6007 {
6008 int8 digit = (*cp - '0');
6009
6010 if (unlikely(pg_mul_s32_overflow(val, 10, &val)) ||
6012 ereport(ERROR,
6013 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
6014 errmsg("number is out of range")));
6015 ADVANCE_PARSE_POINTER(cp, end_ptr);
6016 found = true;
6017 }
6018
6019 *ptr = cp;
6020 *value = val;
6021
6022 return found;
6023}
int8_t int8
Definition: c.h:482
#define unlikely(x)
Definition: c.h:333
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 6049 of file varlena.c.

6052{
6053 const char *cp = start_ptr;
6054 int n;
6055
6056 /* set defaults for output parameters */
6057 *argpos = -1;
6058 *widthpos = -1;
6059 *flags = 0;
6060 *width = 0;
6061
6062 /* try to identify first number */
6063 if (text_format_parse_digits(&cp, end_ptr, &n))
6064 {
6065 if (*cp != '$')
6066 {
6067 /* Must be just a width and a type, so we're done */
6068 *width = n;
6069 return cp;
6070 }
6071 /* The number was argument position */
6072 *argpos = n;
6073 /* Explicit 0 for argument index is immediately refused */
6074 if (n == 0)
6075 ereport(ERROR,
6076 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6077 errmsg("format specifies argument 0, but arguments are numbered from 1")));
6078 ADVANCE_PARSE_POINTER(cp, end_ptr);
6079 }
6080
6081 /* Handle flags (only minus is supported now) */
6082 while (*cp == '-')
6083 {
6084 *flags |= TEXT_FORMAT_FLAG_MINUS;
6085 ADVANCE_PARSE_POINTER(cp, end_ptr);
6086 }
6087
6088 if (*cp == '*')
6089 {
6090 /* Handle indirect width */
6091 ADVANCE_PARSE_POINTER(cp, end_ptr);
6092 if (text_format_parse_digits(&cp, end_ptr, &n))
6093 {
6094 /* number in this position must be closed by $ */
6095 if (*cp != '$')
6096 ereport(ERROR,
6097 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6098 errmsg("width argument position must be ended by \"$\"")));
6099 /* The number was width argument position */
6100 *widthpos = n;
6101 /* Explicit 0 for argument index is immediately refused */
6102 if (n == 0)
6103 ereport(ERROR,
6104 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6105 errmsg("format specifies argument 0, but arguments are numbered from 1")));
6106 ADVANCE_PARSE_POINTER(cp, end_ptr);
6107 }
6108 else
6109 *widthpos = 0; /* width's argument position is unspecified */
6110 }
6111 else
6112 {
6113 /* Check for direct width specification */
6114 if (text_format_parse_digits(&cp, end_ptr, &n))
6115 *width = n;
6116 }
6117
6118 /* cp should now be pointing at type character */
6119 return cp;
6120}
static bool text_format_parse_digits(const char **ptr, const char *end_ptr, int *value)
Definition: varlena.c:6000

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

6130{
6131 char *str;
6132
6133 /* Handle NULL arguments before trying to stringify the value. */
6134 if (isNull)
6135 {
6136 if (conversion == 's')
6137 text_format_append_string(buf, "", flags, width);
6138 else if (conversion == 'L')
6139 text_format_append_string(buf, "NULL", flags, width);
6140 else if (conversion == 'I')
6141 ereport(ERROR,
6142 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
6143 errmsg("null values cannot be formatted as an SQL identifier")));
6144 return;
6145 }
6146
6147 /* Stringify. */
6148 str = OutputFunctionCall(typOutputInfo, value);
6149
6150 /* Escape. */
6151 if (conversion == 'I')
6152 {
6153 /* quote_identifier may or may not allocate a new string. */
6155 }
6156 else if (conversion == 'L')
6157 {
6158 char *qstr = quote_literal_cstr(str);
6159
6160 text_format_append_string(buf, qstr, flags, width);
6161 /* quote_literal_cstr() always allocates a new string */
6162 pfree(qstr);
6163 }
6164 else
6165 text_format_append_string(buf, str, flags, width);
6166
6167 /* Cleanup. */
6168 pfree(str);
6169}
char * quote_literal_cstr(const char *rawstr)
Definition: quote.c:103
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12947
static void text_format_append_string(StringInfo buf, const char *str, int flags, int width)
Definition: varlena.c:6175

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

4586{
4588 collid,
4589 PointerGetDatum(txt1),
4590 PointerGetDatum(txt2)));
4591}
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 5623 of file varlena.c.

5624{
5625 int n = PG_GETARG_INT32(1);
5626
5627 if (n < 0)
5628 {
5630 const char *p = VARDATA_ANY(str);
5631 int len = VARSIZE_ANY_EXHDR(str);
5632 int rlen;
5633
5634 n = pg_mbstrlen_with_len(p, len) + n;
5635 rlen = pg_mbcharcliplen(p, len, n);
5637 }
5638 else
5640}
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 3406 of file varlena.c.

3407{
3408 text *s = PG_GETARG_TEXT_PP(0);
3409 Name result;
3410 int len;
3411
3413
3414 /* Truncate oversize input */
3415 if (len >= NAMEDATALEN)
3417
3418 /* We use palloc0 here to ensure result is zero-padded */
3419 result = (Name) palloc0(NAMEDATALEN);
3420 memcpy(NameStr(*result), VARDATA_ANY(s), len);
3421
3422 PG_RETURN_NAME(result);
3423}
NameData * Name
Definition: c.h:701
#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:1500

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

5669{
5671 const char *p = VARDATA_ANY(str);
5672 int len = VARSIZE_ANY_EXHDR(str);
5673 const char *endp = p + len;
5674 text *result;
5675 char *dst;
5676
5677 result = palloc(len + VARHDRSZ);
5678 dst = (char *) VARDATA(result) + len;
5679 SET_VARSIZE(result, len + VARHDRSZ);
5680
5682 {
5683 /* multibyte version */
5684 while (p < endp)
5685 {
5686 int sz;
5687
5688 sz = pg_mblen(p);
5689 dst -= sz;
5690 memcpy(dst, p, sz);
5691 p += sz;
5692 }
5693 }
5694 else
5695 {
5696 /* single byte version */
5697 while (p < endp)
5698 *(--dst) = *p++;
5699 }
5700
5701 PG_RETURN_TEXT_P(result);
5702}

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

5648{
5650 const char *p = VARDATA_ANY(str);
5651 int len = VARSIZE_ANY_EXHDR(str);
5652 int n = PG_GETARG_INT32(1);
5653 int off;
5654
5655 if (n < 0)
5656 n = -n;
5657 else
5658 n = pg_mbstrlen_with_len(p, len) - n;
5659 off = pg_mbcharcliplen(p, len, n);
5660
5662}

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

4600{
4601 SplitTextOutputData tstate;
4602
4603 /* For array output, tstate should start as all zeroes */
4604 memset(&tstate, 0, sizeof(tstate));
4605
4606 if (!split_text(fcinfo, &tstate))
4608
4609 if (tstate.astate == NULL)
4611
4614}
#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:4676

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

4626{
4627 return text_to_array(fcinfo);
4628}
Datum text_to_array(PG_FUNCTION_ARGS)
Definition: varlena.c:4599

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:1202
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 4636 of file varlena.c.

4637{
4638 ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo;
4639 SplitTextOutputData tstate;
4640
4641 tstate.astate = NULL;
4643 tstate.tupstore = rsi->setResult;
4644 tstate.tupdesc = rsi->setDesc;
4645
4646 (void) split_text(fcinfo, &tstate);
4647
4648 return (Datum) 0;
4649}
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 4660 of file varlena.c.

4661{
4662 return text_to_table(fcinfo);
4663}
Datum text_to_table(PG_FUNCTION_ARGS)
Definition: varlena.c:4636

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

3447{
3448 char *rawname;
3449 List *result = NIL;
3450 List *namelist;
3451 ListCell *l;
3452
3453 /* Convert to C string (handles possible detoasting). */
3454 /* Note we rely on being able to modify rawname below. */
3455 rawname = text_to_cstring(textval);
3456
3457 if (!SplitIdentifierString(rawname, '.', &namelist))
3458 ereport(ERROR,
3459 (errcode(ERRCODE_INVALID_NAME),
3460 errmsg("invalid name syntax")));
3461
3462 if (namelist == NIL)
3463 ereport(ERROR,
3464 (errcode(ERRCODE_INVALID_NAME),
3465 errmsg("invalid name syntax")));
3466
3467 foreach(l, namelist)
3468 {
3469 char *curname = (char *) lfirst(l);
3470
3471 result = lappend(result, makeString(pstrdup(curname)));
3472 }
3473
3474 pfree(rawname);
3475 list_free(namelist);
3476
3477 return result;
3478}
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:3504

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

5042{
5044
5046}
uint32_t uint32
Definition: c.h:488
static text * convert_to_base(uint64 value, int base)
Definition: varlena.c:5015

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

◆ to_bin64()

Datum to_bin64 ( PG_FUNCTION_ARGS  )

Definition at line 5048 of file varlena.c.

5049{
5051
5053}

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

◆ to_hex32()

Datum to_hex32 ( PG_FUNCTION_ARGS  )

Definition at line 5079 of file varlena.c.

5080{
5082
5084}

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

5087{
5089
5091}

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

◆ to_oct32()

Datum to_oct32 ( PG_FUNCTION_ARGS  )

Definition at line 5060 of file varlena.c.

5061{
5063
5065}

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

◆ to_oct64()

Datum to_oct64 ( PG_FUNCTION_ARGS  )

Definition at line 5067 of file varlena.c.

5068{
5070
5072}

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

◆ unicode_assigned()

Datum unicode_assigned ( PG_FUNCTION_ARGS  )

Definition at line 6401 of file varlena.c.

6402{
6404 unsigned char *p;
6405 int size;
6406
6408 ereport(ERROR,
6409 (errmsg("Unicode categorization can only be performed if server encoding is UTF8")));
6410
6411 /* convert to pg_wchar */
6413 p = (unsigned char *) VARDATA_ANY(input);
6414 for (int i = 0; i < size; i++)
6415 {
6416 pg_wchar uchar = utf8_to_unicode(p);
6417 int category = unicode_category(uchar);
6418
6419 if (category == PG_U_UNASSIGNED)
6420 PG_RETURN_BOOL(false);
6421
6422 p += pg_utf_mblen(p);
6423 }
6424
6425 PG_RETURN_BOOL(true);
6426}
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
static pg_noinline void Size size
Definition: slab.c:607
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, size, unicode_category(), utf8_to_unicode(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

◆ unicode_is_normalized()

Datum unicode_is_normalized ( PG_FUNCTION_ARGS  )

Definition at line 6495 of file varlena.c.

6496{
6498 char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
6500 int size;
6501 pg_wchar *input_chars;
6502 pg_wchar *output_chars;
6503 unsigned char *p;
6504 int i;
6505 UnicodeNormalizationQC quickcheck;
6506 int output_size;
6507 bool result;
6508
6509 form = unicode_norm_form_from_string(formstr);
6510
6511 /* convert to pg_wchar */
6513 input_chars = palloc((size + 1) * sizeof(pg_wchar));
6514 p = (unsigned char *) VARDATA_ANY(input);
6515 for (i = 0; i < size; i++)
6516 {
6517 input_chars[i] = utf8_to_unicode(p);
6518 p += pg_utf_mblen(p);
6519 }
6520 input_chars[i] = (pg_wchar) '\0';
6521 Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
6522
6523 /* quick check (see UAX #15) */
6524 quickcheck = unicode_is_normalized_quickcheck(form, input_chars);
6525 if (quickcheck == UNICODE_NORM_QC_YES)
6526 PG_RETURN_BOOL(true);
6527 else if (quickcheck == UNICODE_NORM_QC_NO)
6528 PG_RETURN_BOOL(false);
6529
6530 /* normalize and compare with original */
6531 output_chars = unicode_normalize(form, input_chars);
6532
6533 output_size = 0;
6534 for (pg_wchar *wp = output_chars; *wp; wp++)
6535 output_size++;
6536
6537 result = (size == output_size) &&
6538 (memcmp(input_chars, output_chars, size * sizeof(pg_wchar)) == 0);
6539
6540 PG_RETURN_BOOL(result);
6541}
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:6341

References Assert, i, input, palloc(), PG_GETARG_TEXT_PP, pg_mbstrlen_with_len(), PG_RETURN_BOOL, pg_utf_mblen, size, 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 6341 of file varlena.c.

6342{
6343 UnicodeNormalizationForm form = -1;
6344
6345 /*
6346 * Might as well check this while we're here.
6347 */
6349 ereport(ERROR,
6350 (errcode(ERRCODE_SYNTAX_ERROR),
6351 errmsg("Unicode normalization can only be performed if server encoding is UTF8")));
6352
6353 if (pg_strcasecmp(formstr, "NFC") == 0)
6354 form = UNICODE_NFC;
6355 else if (pg_strcasecmp(formstr, "NFD") == 0)
6356 form = UNICODE_NFD;
6357 else if (pg_strcasecmp(formstr, "NFKC") == 0)
6358 form = UNICODE_NFKC;
6359 else if (pg_strcasecmp(formstr, "NFKD") == 0)
6360 form = UNICODE_NFKD;
6361 else
6362 ereport(ERROR,
6363 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6364 errmsg("invalid normalization form: %s", formstr)));
6365
6366 return form;
6367}
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 6429 of file varlena.c.

6430{
6432 char *formstr = text_to_cstring(PG_GETARG_TEXT_PP(1));
6434 int size;
6435 pg_wchar *input_chars;
6436 pg_wchar *output_chars;
6437 unsigned char *p;
6438 text *result;
6439 int i;
6440
6441 form = unicode_norm_form_from_string(formstr);
6442
6443 /* convert to pg_wchar */
6445 input_chars = palloc((size + 1) * sizeof(pg_wchar));
6446 p = (unsigned char *) VARDATA_ANY(input);
6447 for (i = 0; i < size; i++)
6448 {
6449 input_chars[i] = utf8_to_unicode(p);
6450 p += pg_utf_mblen(p);
6451 }
6452 input_chars[i] = (pg_wchar) '\0';
6453 Assert((char *) p == VARDATA_ANY(input) + VARSIZE_ANY_EXHDR(input));
6454
6455 /* action */
6456 output_chars = unicode_normalize(form, input_chars);
6457
6458 /* convert back to UTF-8 string */
6459 size = 0;
6460 for (pg_wchar *wp = output_chars; *wp; wp++)
6461 {
6462 unsigned char buf[4];
6463
6464 unicode_to_utf8(*wp, buf);
6465 size += pg_utf_mblen(buf);
6466 }
6467
6468 result = palloc(size + VARHDRSZ);
6469 SET_VARSIZE(result, size + VARHDRSZ);
6470
6471 p = (unsigned char *) VARDATA_ANY(result);
6472 for (pg_wchar *wp = output_chars; *wp; wp++)
6473 {
6474 unicode_to_utf8(*wp, p);
6475 p += pg_utf_mblen(p);
6476 }
6477 Assert((char *) p == (char *) result + size + VARHDRSZ);
6478
6479 PG_RETURN_TEXT_P(result);
6480}
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, size, 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 6378 of file varlena.c.

6379{
6381}
#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 6587 of file varlena.c.

6588{
6589 text *input_text = PG_GETARG_TEXT_PP(0);
6590 char *instr;
6591 int len;
6593 text *result;
6594 pg_wchar pair_first = 0;
6595 char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1];
6596
6597 instr = VARDATA_ANY(input_text);
6598 len = VARSIZE_ANY_EXHDR(input_text);
6599
6601
6602 while (len > 0)
6603 {
6604 if (instr[0] == '\\')
6605 {
6606 if (len >= 2 &&
6607 instr[1] == '\\')
6608 {
6609 if (pair_first)
6610 goto invalid_pair;
6611 appendStringInfoChar(&str, '\\');
6612 instr += 2;
6613 len -= 2;
6614 }
6615 else if ((len >= 5 && isxdigits_n(instr + 1, 4)) ||
6616 (len >= 6 && instr[1] == 'u' && isxdigits_n(instr + 2, 4)))
6617 {
6618 pg_wchar unicode;
6619 int offset = instr[1] == 'u' ? 2 : 1;
6620
6621 unicode = hexval_n(instr + offset, 4);
6622
6623 if (!is_valid_unicode_codepoint(unicode))
6624 ereport(ERROR,
6625 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6626 errmsg("invalid Unicode code point: %04X", unicode));
6627
6628 if (pair_first)
6629 {
6630 if (is_utf16_surrogate_second(unicode))
6631 {
6632 unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6633 pair_first = 0;
6634 }
6635 else
6636 goto invalid_pair;
6637 }
6638 else if (is_utf16_surrogate_second(unicode))
6639 goto invalid_pair;
6640
6641 if (is_utf16_surrogate_first(unicode))
6642 pair_first = unicode;
6643 else
6644 {
6645 pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6647 }
6648
6649 instr += 4 + offset;
6650 len -= 4 + offset;
6651 }
6652 else if (len >= 8 && instr[1] == '+' && isxdigits_n(instr + 2, 6))
6653 {
6654 pg_wchar unicode;
6655
6656 unicode = hexval_n(instr + 2, 6);
6657
6658 if (!is_valid_unicode_codepoint(unicode))
6659 ereport(ERROR,
6660 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6661 errmsg("invalid Unicode code point: %04X", unicode));
6662
6663 if (pair_first)
6664 {
6665 if (is_utf16_surrogate_second(unicode))
6666 {
6667 unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6668 pair_first = 0;
6669 }
6670 else
6671 goto invalid_pair;
6672 }
6673 else if (is_utf16_surrogate_second(unicode))
6674 goto invalid_pair;
6675
6676 if (is_utf16_surrogate_first(unicode))
6677 pair_first = unicode;
6678 else
6679 {
6680 pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6682 }
6683
6684 instr += 8;
6685 len -= 8;
6686 }
6687 else if (len >= 10 && instr[1] == 'U' && isxdigits_n(instr + 2, 8))
6688 {
6689 pg_wchar unicode;
6690
6691 unicode = hexval_n(instr + 2, 8);
6692
6693 if (!is_valid_unicode_codepoint(unicode))
6694 ereport(ERROR,
6695 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
6696 errmsg("invalid Unicode code point: %04X", unicode));
6697
6698 if (pair_first)
6699 {
6700 if (is_utf16_surrogate_second(unicode))
6701 {
6702 unicode = surrogate_pair_to_codepoint(pair_first, unicode);
6703 pair_first = 0;
6704 }
6705 else
6706 goto invalid_pair;
6707 }
6708 else if (is_utf16_surrogate_second(unicode))
6709 goto invalid_pair;
6710
6711 if (is_utf16_surrogate_first(unicode))
6712 pair_first = unicode;
6713 else
6714 {
6715 pg_unicode_to_server(unicode, (unsigned char *) cbuf);
6717 }
6718
6719 instr += 10;
6720 len -= 10;
6721 }
6722 else
6723 ereport(ERROR,
6724 (errcode(ERRCODE_SYNTAX_ERROR),
6725 errmsg("invalid Unicode escape"),
6726 errhint("Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX.")));
6727 }
6728 else
6729 {
6730 if (pair_first)
6731 goto invalid_pair;
6732
6733 appendStringInfoChar(&str, *instr++);
6734 len--;
6735 }
6736 }
6737
6738 /* unfinished surrogate pair? */
6739 if (pair_first)
6740 goto invalid_pair;
6741
6742 result = cstring_to_text_with_len(str.data, str.len);
6743 pfree(str.data);
6744
6745 PG_RETURN_TEXT_P(result);
6746
6747invalid_pair:
6748 ereport(ERROR,
6749 (errcode(ERRCODE_SYNTAX_ERROR),
6750 errmsg("invalid Unicode surrogate pair")));
6751 PG_RETURN_NULL(); /* keep compiler quiet */
6752}
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:6573
static bool isxdigits_n(const char *instr, size_t n)
Definition: varlena.c:6547

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

6294{
6295 int dist;
6296
6297 Assert(state);
6298
6299 if (state->source == NULL || state->source[0] == '\0' ||
6300 candidate == NULL || candidate[0] == '\0')
6301 return;
6302
6303 /*
6304 * To avoid ERROR-ing, we check the lengths here instead of setting
6305 * 'trusted' to false in the call to varstr_levenshtein_less_equal().
6306 */
6307 if (strlen(state->source) > MAX_LEVENSHTEIN_STRLEN ||
6308 strlen(candidate) > MAX_LEVENSHTEIN_STRLEN)
6309 return;
6310
6311 dist = varstr_levenshtein_less_equal(state->source, strlen(state->source),
6312 candidate, strlen(candidate), 1, 1, 1,
6313 state->max_d, true);
6314 if (dist <= state->max_d &&
6315 dist <= strlen(state->source) / 2 &&
6316 (state->min_d == -1 || dist < state->min_d))
6317 {
6318 state->min_d = dist;
6319 state->match = candidate;
6320 }
6321}
#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:1541
#define PG_CACHE_LINE_SIZE
bool pg_strxfrm_prefix_enabled(pg_locale_t locale)
Definition: pg_locale.c:1566
size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale)
Definition: pg_locale.c:1530
size_t pg_strxfrm_prefix(char *dest, const char *src, size_t destsize, pg_locale_t locale)
Definition: pg_locale.c:1577
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(), res, 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:1514
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:1480

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