39 #define PG_GETARG_TEXT_PP_IF_EXISTS(_n) \
40 (PG_NARGS() > (_n) ? PG_GETARG_TEXT_PP(_n) : NULL)
90 #ifndef MAX_CACHED_RES
91 #define MAX_CACHED_RES 32
113 bool use_subpatterns,
114 bool ignore_degenerate);
151 if (re_array[i].cre_pat_len == text_re_len &&
152 re_array[i].cre_flags == cflags &&
153 re_array[i].cre_collation == collation &&
154 memcmp(re_array[i].cre_pat, text_re_val, text_re_len) == 0)
161 re_temp = re_array[
i];
163 re_array[0] = re_temp;
166 return &re_array[0].
cre_re;
203 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
204 errmsg(
"invalid regular expression: %s", errMsg)));
218 (
errcode(ERRCODE_OUT_OF_MEMORY),
219 errmsg(
"out of memory")));
221 memcpy(re_temp.
cre_pat, text_re_val, text_re_len);
235 free(re_array[num_res].cre_pat);
241 re_array[0] = re_temp;
244 return &re_array[0].
cre_re;
263 int start_search,
int nmatch,
regmatch_t *pmatch)
282 pg_regerror(regexec_result, re, errMsg,
sizeof(errMsg));
284 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
285 errmsg(
"regular expression failed: %s", errMsg)));
288 return (regexec_result ==
REG_OKAY);
340 int cflags,
Oid collation,
348 return RE_execute(re, dat, dat_len, nmatch, pmatch);
374 for (i = 0; i < opt_len; i++)
421 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
422 errmsg(
"invalid regexp option: \"%c\"",
586 so = pmatch[1].
rm_so;
587 eo = pmatch[1].
rm_eo;
592 so = pmatch[0].
rm_so;
593 eo = pmatch[0].
rm_eo;
602 if (so < 0 || eo < 0)
668 bool afterescape =
false;
669 bool incharclass =
false;
695 if (escape_mblen > 1)
697 (
errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
698 errmsg(
"invalid escape string"),
699 errhint(
"Escape string must be empty or one character.")));
757 else if (e && elen == mblen && memcmp(e, p, mblen) == 0)
783 if (pchar ==
'"' && !incharclass)
784 *r++ = ((nquotes++ % 2) == 0) ?
'(' :
')';
792 else if (e && pchar == *e)
797 else if (incharclass)
805 else if (pchar ==
'[')
810 else if (pchar ==
'%')
815 else if (pchar ==
'_')
817 else if (pchar ==
'(')
824 else if (pchar ==
'\\' || pchar ==
'.' ||
825 pchar ==
'^' || pchar ==
'$')
916 bool force_glob,
bool use_subpatterns,
917 bool ignore_degenerate)
947 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
948 errmsg(
"regexp_split does not support the global option")));
950 re_flags.
glob =
true;
957 if (use_subpatterns && cpattern->
re_nsub > 0)
960 pmatch_len = cpattern->
re_nsub + 1;
964 use_subpatterns =
false;
973 array_len = re_flags.
glob ? 256 : 32;
988 if (!ignore_degenerate ||
989 (pmatch[0].rm_so < wide_len &&
990 pmatch[0].rm_eo > prev_match_end))
993 while (array_idx + matchctx->
npatterns * 2 > array_len)
997 sizeof(
int) * array_len);
1001 if (use_subpatterns)
1005 for (i = 1; i <= matchctx->
npatterns; i++)
1018 prev_match_end = pmatch[0].
rm_eo;
1030 start_search = prev_match_end;
1031 if (pmatch[0].rm_so == pmatch[0].rm_eo)
1033 if (start_search > wide_len)
1052 if (matchctx->
elems)
1054 if (matchctx->
nulls)
1066 bool *nulls = matchctx->
nulls;
1074 for (i = 0; i < matchctx->
npatterns; i++)
1079 if (so < 0 || eo < 0)
1216 elog(
ERROR,
"invalid match ending position");
1221 if (endpos < startpos)
1222 elog(
ERROR,
"invalid match starting position");
1260 if (case_insensitive)
1285 pg_regerror(re_result, re, errMsg,
sizeof(errMsg));
1287 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
1288 errmsg(
"regular expression failed: %s", errMsg)));
1294 result = (
char *)
palloc(maxlen);
static bool RE_execute(regex_t *re, char *dat, int dat_len, int nmatch, regmatch_t *pmatch)
text * replace_text_regexp(text *src_text, void *regexp, text *replace_text, bool glob)
Datum textregexsubstr(PG_FUNCTION_ARGS)
int errhint(const char *fmt,...)
Datum regexp_matches(PG_FUNCTION_ARGS)
Datum regexp_matches_no_flags(PG_FUNCTION_ARGS)
Datum nameregexeq(PG_FUNCTION_ARGS)
#define SRF_IS_FIRSTCALL()
#define PointerGetDatum(X)
Datum texticregexne(PG_FUNCTION_ARGS)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Datum regexp_split_to_table_no_flags(PG_FUNCTION_ARGS)
int errcode(int sqlerrcode)
Datum textregexeq(PG_FUNCTION_ARGS)
Datum regexp_split_to_array(PG_FUNCTION_ARGS)
struct cached_re_str cached_re_str
#define SRF_PERCALL_SETUP()
int pg_regcomp(regex_t *re, const chr *string, size_t len, int flags, Oid collation)
#define PG_GET_COLLATION()
int pg_regprefix(regex_t *re, chr **string, size_t *slength)
#define PG_GETARG_TEXT_P_COPY(n)
#define PG_GETARG_TEXT_PP(n)
int pg_mbstrlen_with_len(const char *mbstr, int limit)
#define SRF_RETURN_NEXT(_funcctx, _result)
#define PG_GETARG_TEXT_PP_IF_EXISTS(_n)
void pfree(void *pointer)
static cached_re_str re_array[MAX_CACHED_RES]
Datum texticregexeq(PG_FUNCTION_ARGS)
struct regexp_matches_ctx regexp_matches_ctx
int pg_database_encoding_max_length(void)
static bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
Datum textregexreplace_noopt(PG_FUNCTION_ARGS)
Datum nameicregexne(PG_FUNCTION_ARGS)
Datum similar_escape(PG_FUNCTION_ARGS)
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
MemoryContext CurrentMemoryContext
Datum text_substr_no_len(PG_FUNCTION_ARGS)
static void cleanup_regexp_matches(regexp_matches_ctx *matchctx)
Datum regexp_split_to_table(PG_FUNCTION_ARGS)
#define PG_RETURN_ARRAYTYPE_P(x)
Datum textregexne(PG_FUNCTION_ARGS)
#define ereport(elevel, rest)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
Datum nameicregexeq(PG_FUNCTION_ARGS)
static regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation)
Datum text_substr(PG_FUNCTION_ARGS)
void * palloc0(Size size)
#define PG_RETURN_BOOL(x)
static regexp_matches_ctx * setup_regexp_matches(text *orig_str, text *pattern, text *flags, Oid collation, bool force_glob, bool use_subpatterns, bool ignore_degenerate)
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
#define PG_RETURN_TEXT_P(x)
#define Assert(condition)
static ArrayType * build_regexp_matches_result(regexp_matches_ctx *matchctx)
MemoryContext multi_call_memory_ctx
static XLogRecPtr startpos
int pg_mblen(const char *mbstr)
void * repalloc(void *pointer, Size size)
Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS)
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum nameregexne(PG_FUNCTION_ARGS)
static Datum build_regexp_split_result(regexp_matches_ctx *splitctx)
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)
#define VARSIZE_ANY_EXHDR(PTR)
char * regexp_fixed_prefix(text *text_re, bool case_insensitive, Oid collation, bool *exact)
int errmsg(const char *fmt,...)
static void parse_re_flags(pg_re_flags *flags, text *opts)
static bool RE_wchar_execute(regex_t *re, pg_wchar *data, int data_len, int start_search, int nmatch, regmatch_t *pmatch)
#define CHECK_FOR_INTERRUPTS()
#define SET_VARSIZE(PTR, len)
Datum textregexreplace(PG_FUNCTION_ARGS)
int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len)
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
void pg_regfree(regex_t *re)
#define DirectFunctionCall2(func, arg1, arg2)
struct pg_re_flags pg_re_flags
#define PG_GETARG_NAME(n)
#define SRF_RETURN_DONE(_funcctx)
#define SRF_FIRSTCALL_INIT()