41 #define PG_GETARG_TEXT_PP_IF_EXISTS(_n) \
42 (PG_NARGS() > (_n) ? PG_GETARG_TEXT_PP(_n) : NULL)
95 #ifndef MAX_CACHED_RES
96 #define MAX_CACHED_RES 32
122 bool use_subpatterns,
123 bool ignore_degenerate,
124 bool fetching_unmatched);
161 if (
re_array[
i].cre_pat_len == text_re_len &&
163 re_array[
i].cre_collation == collation &&
164 memcmp(
re_array[
i].cre_pat, text_re_val, text_re_len) == 0)
184 "RegexpCacheMemoryContext",
206 "RegexpMemoryContext",
223 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
224 errmsg(
"invalid regular expression: %s", errMsg)));
229 memcpy(re_temp.
cre_pat, text_re_val, text_re_len);
235 re_temp.
cre_pat[text_re_len] = 0;
284 int start_search,
int nmatch,
regmatch_t *pmatch)
302 pg_regerror(regexec_result, re, errMsg,
sizeof(errMsg));
304 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
305 errmsg(
"regular expression failed: %s", errMsg)));
308 return (regexec_result ==
REG_OKAY);
360 int cflags,
Oid collation,
372 return RE_execute(re, dat, dat_len, nmatch, pmatch);
398 for (
i = 0;
i < opt_len;
i++)
445 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
446 errmsg(
"invalid regular expression option: \"%.*s\"",
610 so = pmatch[1].
rm_so;
611 eo = pmatch[1].
rm_eo;
616 so = pmatch[0].
rm_so;
617 eo = pmatch[0].
rm_eo;
626 if (so < 0 || eo < 0)
678 if (*opt_p >=
'0' && *opt_p <=
'9')
680 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
681 errmsg(
"invalid regular expression option: \"%.*s\"",
683 errhint(
"If you meant to use regexp_replace() with a start parameter, cast the fourth argument to integer explicitly.")));
690 0, flags.
glob ? 0 : 1));
716 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
717 errmsg(
"invalid value for parameter \"%s\": %d",
725 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
726 errmsg(
"invalid value for parameter \"%s\": %d",
735 n = re_flags.
glob ? 0 : 1;
776 bool afterescape =
false;
777 bool incharclass =
false;
782 if (esc_text == NULL)
798 if (escape_mblen > 1)
800 (
errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
801 errmsg(
"invalid escape string"),
802 errhint(
"Escape string must be empty or one character.")));
882 else if (
e && elen == mblen && memcmp(
e, p, mblen) == 0)
908 if (pchar ==
'"' && !incharclass)
922 else if (nquotes == 1)
936 (
errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
937 errmsg(
"SQL regular expression may not contain more than two escape-double-quote separators")));
952 else if (
e && pchar == *
e)
957 else if (incharclass)
965 else if (pchar ==
'[')
970 else if (pchar ==
'%')
975 else if (pchar ==
'_')
977 else if (pchar ==
'(')
984 else if (pchar ==
'\\' || pchar ==
'.' ||
985 pchar ==
'^' || pchar ==
'$')
1082 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1083 errmsg(
"invalid value for parameter \"%s\": %d",
1092 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1094 errmsg(
"%s does not support the \"global\" option",
1095 "regexp_count()")));
1097 re_flags.
glob =
true;
1146 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1147 errmsg(
"invalid value for parameter \"%s\": %d",
1155 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1156 errmsg(
"invalid value for parameter \"%s\": %d",
1162 if (endoption != 0 && endoption != 1)
1164 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1165 errmsg(
"invalid value for parameter \"%s\": %d",
1166 "endoption", endoption)));
1173 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1174 errmsg(
"invalid value for parameter \"%s\": %d",
1175 "subexpr", subexpr)));
1183 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1185 errmsg(
"%s does not support the \"global\" option",
1186 "regexp_instr()")));
1188 re_flags.
glob =
true;
1270 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1272 errmsg(
"%s does not support the \"global\" option",
1309 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1311 errmsg(
"%s does not support the \"global\" option",
1313 errhint(
"Use the regexp_matches function instead.")));
1364 true,
false,
false);
1420 bool use_subpatterns,
1421 bool ignore_degenerate,
1422 bool fetching_unmatched)
1436 int prev_valid_match_end;
1448 cflags = re_flags->
cflags;
1449 if (!use_subpatterns)
1454 if (use_subpatterns && cpattern->
re_nsub > 0)
1457 pmatch_len = cpattern->
re_nsub + 1;
1461 use_subpatterns =
false;
1475 array_len = re_flags->
glob ? 255 : 31;
1481 prev_valid_match_end = 0;
1483 pmatch_len, pmatch))
1490 if (!ignore_degenerate ||
1491 (pmatch[0].rm_so < wide_len &&
1492 pmatch[0].rm_eo > prev_match_end))
1495 while (array_idx + matchctx->
npatterns * 2 + 1 > array_len)
1497 array_len += array_len + 1;
1500 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1501 errmsg(
"too many regular expression matches")));
1503 sizeof(
int) * array_len);
1507 if (use_subpatterns)
1513 int so = pmatch[
i].
rm_so;
1514 int eo = pmatch[
i].
rm_eo;
1518 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)
1524 int so = pmatch[0].
rm_so;
1525 int eo = pmatch[0].
rm_eo;
1529 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)
1539 if (fetching_unmatched &&
1540 pmatch[0].rm_so >= 0 &&
1541 (pmatch[0].rm_so - prev_valid_match_end) > maxlen)
1542 maxlen = (pmatch[0].rm_so - prev_valid_match_end);
1543 prev_valid_match_end = pmatch[0].
rm_eo;
1545 prev_match_end = pmatch[0].
rm_eo;
1548 if (!re_flags->
glob)
1557 start_search = prev_match_end;
1558 if (pmatch[0].rm_so == pmatch[0].rm_eo)
1560 if (start_search > wide_len)
1568 if (fetching_unmatched &&
1569 (wide_len - prev_valid_match_end) > maxlen)
1570 maxlen = (wide_len - prev_valid_match_end);
1580 int64 maxsiz = eml * (int64) maxlen;
1593 if (maxsiz > orig_len)
1594 conv_bufsiz = orig_len + 1;
1596 conv_bufsiz = maxsiz + 1;
1625 bool *nulls = matchctx->
nulls;
1638 if (so < 0 || eo < 0)
1649 Assert(len < matchctx->conv_bufsiz);
1668 TEXTOID, -1,
false, TYPALIGN_INT);
1697 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1699 errmsg(
"%s does not support the \"global\" option",
1700 "regexp_split_to_table()")));
1702 re_flags.
glob =
true;
1752 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1754 errmsg(
"%s does not support the \"global\" option",
1755 "regexp_split_to_array()")));
1757 re_flags.
glob =
true;
1803 elog(
ERROR,
"invalid match ending position");
1807 elog(
ERROR,
"invalid match starting position");
1816 Assert(len < splitctx->conv_bufsiz);
1853 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1854 errmsg(
"invalid value for parameter \"%s\": %d",
1862 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1863 errmsg(
"invalid value for parameter \"%s\": %d",
1871 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1872 errmsg(
"invalid value for parameter \"%s\": %d",
1873 "subexpr", subexpr)));
1881 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1883 errmsg(
"%s does not support the \"global\" option",
1884 "regexp_substr()")));
1886 re_flags.
glob =
true;
1910 if (so < 0 || eo < 0)
1970 if (case_insensitive)
1994 pg_regerror(re_result, re, errMsg,
sizeof(errMsg));
1996 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
1997 errmsg(
"regular expression failed: %s", errMsg)));
2003 result = (
char *)
palloc(maxlen);
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)
ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
elog(ERROR, "%s: %s", p2, msg)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define PG_GETARG_TEXT_PP(n)
#define PG_GETARG_NAME(n)
#define PG_RETURN_TEXT_P(x)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_RETURN_DATUM(x)
#define DirectFunctionCall3(func, arg1, arg2, arg3)
#define PG_GET_COLLATION()
#define PG_GETARG_TEXT_P_COPY(n)
#define PG_RETURN_BOOL(x)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
#define SRF_RETURN_DONE(_funcctx)
if(TABLE==NULL||TABLE_index==NULL)
Assert(fmt[strlen(fmt) - 1] !='\n')
int pg_mbstrlen_with_len(const char *mbstr, int limit)
int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len)
int pg_database_encoding_max_length(void)
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
int pg_mblen(const char *mbstr)
void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
void MemoryContextDelete(MemoryContext context)
void MemoryContextSetIdentifier(MemoryContext context, const char *id)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static AmcheckOptions opts
static XLogRecPtr startpos
static Datum PointerGetDatum(const void *X)
static Datum Int32GetDatum(int32 X)
int pg_regcomp(regex_t *re, const chr *string, size_t len, int flags, Oid collation)
size_t pg_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
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)
struct regexp_matches_ctx regexp_matches_ctx
static MemoryContext RegexpCacheMemoryContext
Datum regexp_match_no_flags(PG_FUNCTION_ARGS)
Datum textregexreplace(PG_FUNCTION_ARGS)
Datum texticregexne(PG_FUNCTION_ARGS)
Datum regexp_substr_no_start(PG_FUNCTION_ARGS)
struct pg_re_flags pg_re_flags
Datum regexp_split_to_array(PG_FUNCTION_ARGS)
Datum texticregexeq(PG_FUNCTION_ARGS)
Datum regexp_substr_no_n(PG_FUNCTION_ARGS)
Datum regexp_instr_no_subexpr(PG_FUNCTION_ARGS)
Datum similar_to_escape_2(PG_FUNCTION_ARGS)
bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
static bool RE_wchar_execute(regex_t *re, pg_wchar *data, int data_len, int start_search, int nmatch, regmatch_t *pmatch)
Datum regexp_substr(PG_FUNCTION_ARGS)
Datum nameicregexne(PG_FUNCTION_ARGS)
Datum textregexsubstr(PG_FUNCTION_ARGS)
static Datum build_regexp_split_result(regexp_matches_ctx *splitctx)
Datum regexp_split_to_array_no_flags(PG_FUNCTION_ARGS)
Datum textregexreplace_extended_no_n(PG_FUNCTION_ARGS)
static regexp_matches_ctx * setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, int start_search, Oid collation, bool use_subpatterns, bool ignore_degenerate, bool fetching_unmatched)
Datum nameregexne(PG_FUNCTION_ARGS)
Datum regexp_instr(PG_FUNCTION_ARGS)
static ArrayType * build_regexp_match_result(regexp_matches_ctx *matchctx)
Datum similar_to_escape_1(PG_FUNCTION_ARGS)
Datum regexp_substr_no_flags(PG_FUNCTION_ARGS)
Datum regexp_matches(PG_FUNCTION_ARGS)
static text * similar_escape_internal(text *pat_text, text *esc_text)
#define PG_GETARG_TEXT_PP_IF_EXISTS(_n)
Datum nameicregexeq(PG_FUNCTION_ARGS)
Datum regexp_matches_no_flags(PG_FUNCTION_ARGS)
Datum regexp_split_to_table_no_flags(PG_FUNCTION_ARGS)
Datum regexp_match(PG_FUNCTION_ARGS)
Datum textregexreplace_extended(PG_FUNCTION_ARGS)
Datum nameregexeq(PG_FUNCTION_ARGS)
Datum regexp_instr_no_n(PG_FUNCTION_ARGS)
Datum regexp_count_no_start(PG_FUNCTION_ARGS)
struct cached_re_str cached_re_str
regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation)
static cached_re_str re_array[MAX_CACHED_RES]
static bool RE_execute(regex_t *re, char *dat, int dat_len, int nmatch, regmatch_t *pmatch)
static void parse_re_flags(pg_re_flags *flags, text *opts)
char * regexp_fixed_prefix(text *text_re, bool case_insensitive, Oid collation, bool *exact)
Datum regexp_split_to_table(PG_FUNCTION_ARGS)
Datum textregexreplace_noopt(PG_FUNCTION_ARGS)
Datum regexp_like_no_flags(PG_FUNCTION_ARGS)
Datum regexp_instr_no_flags(PG_FUNCTION_ARGS)
Datum textregexeq(PG_FUNCTION_ARGS)
Datum textregexne(PG_FUNCTION_ARGS)
Datum regexp_count_no_flags(PG_FUNCTION_ARGS)
Datum similar_escape(PG_FUNCTION_ARGS)
Datum regexp_instr_no_start(PG_FUNCTION_ARGS)
Datum regexp_instr_no_endoption(PG_FUNCTION_ARGS)
Datum textregexreplace_extended_no_flags(PG_FUNCTION_ARGS)
Datum regexp_like(PG_FUNCTION_ARGS)
Datum regexp_substr_no_subexpr(PG_FUNCTION_ARGS)
Datum regexp_count(PG_FUNCTION_ARGS)
int pg_regprefix(regex_t *re, chr **string, size_t *slength)
MemoryContext multi_call_memory_ctx
MemoryContext cre_context
#define SET_VARSIZE(PTR, len)
#define VARSIZE_ANY_EXHDR(PTR)
Datum text_substr(PG_FUNCTION_ARGS)
text * cstring_to_text_with_len(const char *s, int len)
text * replace_text_regexp(text *src_text, text *pattern_text, text *replace_text, int cflags, Oid collation, int search_start, int n)