40 #define PG_GETARG_TEXT_PP_IF_EXISTS(_n) \
41 (PG_NARGS() > (_n) ? PG_GETARG_TEXT_PP(_n) : NULL)
94 #ifndef MAX_CACHED_RES
95 #define MAX_CACHED_RES 32
121 bool use_subpatterns,
122 bool ignore_degenerate,
123 bool fetching_unmatched);
160 if (
re_array[
i].cre_pat_len == text_re_len &&
162 re_array[
i].cre_collation == collation &&
163 memcmp(
re_array[
i].cre_pat, text_re_val, text_re_len) == 0)
183 "RegexpCacheMemoryContext",
205 "RegexpMemoryContext",
222 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
223 errmsg(
"invalid regular expression: %s", errMsg)));
228 memcpy(re_temp.
cre_pat, text_re_val, text_re_len);
234 re_temp.
cre_pat[text_re_len] = 0;
283 int start_search,
int nmatch,
regmatch_t *pmatch)
301 pg_regerror(regexec_result, re, errMsg,
sizeof(errMsg));
303 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
304 errmsg(
"regular expression failed: %s", errMsg)));
307 return (regexec_result ==
REG_OKAY);
359 int cflags,
Oid collation,
371 return RE_execute(re, dat, dat_len, nmatch, pmatch);
397 for (
i = 0;
i < opt_len;
i++)
444 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
445 errmsg(
"invalid regular expression option: \"%.*s\"",
609 so = pmatch[1].rm_so;
610 eo = pmatch[1].rm_eo;
615 so = pmatch[0].rm_so;
616 eo = pmatch[0].rm_eo;
625 if (so < 0 || eo < 0)
677 if (*opt_p >=
'0' && *opt_p <=
'9')
679 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
680 errmsg(
"invalid regular expression option: \"%.*s\"",
682 errhint(
"If you meant to use regexp_replace() with a start parameter, cast the fourth argument to integer explicitly.")));
689 0, flags.
glob ? 0 : 1));
715 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
716 errmsg(
"invalid value for parameter \"%s\": %d",
724 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
725 errmsg(
"invalid value for parameter \"%s\": %d",
734 n = re_flags.
glob ? 0 : 1;
775 bool afterescape =
false;
776 bool incharclass =
false;
781 if (esc_text == NULL)
797 if (escape_mblen > 1)
799 (
errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
800 errmsg(
"invalid escape string"),
801 errhint(
"Escape string must be empty or one character.")));
881 else if (
e && elen == mblen && memcmp(
e, p, mblen) == 0)
907 if (pchar ==
'"' && !incharclass)
921 else if (nquotes == 1)
935 (
errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),
936 errmsg(
"SQL regular expression may not contain more than two escape-double-quote separators")));
951 else if (
e && pchar == *
e)
956 else if (incharclass)
964 else if (pchar ==
'[')
969 else if (pchar ==
'%')
974 else if (pchar ==
'_')
976 else if (pchar ==
'(')
983 else if (pchar ==
'\\' || pchar ==
'.' ||
984 pchar ==
'^' || pchar ==
'$')
1081 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1082 errmsg(
"invalid value for parameter \"%s\": %d",
1091 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1093 errmsg(
"%s does not support the \"global\" option",
1094 "regexp_count()")));
1096 re_flags.
glob =
true;
1145 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1146 errmsg(
"invalid value for parameter \"%s\": %d",
1154 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1155 errmsg(
"invalid value for parameter \"%s\": %d",
1161 if (endoption != 0 && endoption != 1)
1163 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1164 errmsg(
"invalid value for parameter \"%s\": %d",
1165 "endoption", endoption)));
1172 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1173 errmsg(
"invalid value for parameter \"%s\": %d",
1174 "subexpr", subexpr)));
1182 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1184 errmsg(
"%s does not support the \"global\" option",
1185 "regexp_instr()")));
1187 re_flags.
glob =
true;
1269 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1271 errmsg(
"%s does not support the \"global\" option",
1308 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1310 errmsg(
"%s does not support the \"global\" option",
1312 errhint(
"Use the regexp_matches function instead.")));
1363 true,
false,
false);
1419 bool use_subpatterns,
1420 bool ignore_degenerate,
1421 bool fetching_unmatched)
1435 int prev_valid_match_end;
1447 cflags = re_flags->
cflags;
1448 if (!use_subpatterns)
1453 if (use_subpatterns && cpattern->re_nsub > 0)
1455 matchctx->
npatterns = cpattern->re_nsub;
1456 pmatch_len = cpattern->re_nsub + 1;
1460 use_subpatterns =
false;
1474 array_len = re_flags->
glob ? 255 : 31;
1480 prev_valid_match_end = 0;
1482 pmatch_len, pmatch))
1489 if (!ignore_degenerate ||
1490 (pmatch[0].rm_so < wide_len &&
1491 pmatch[0].rm_eo > prev_match_end))
1494 while (array_idx + matchctx->
npatterns * 2 + 1 > array_len)
1496 array_len += array_len + 1;
1499 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1500 errmsg(
"too many regular expression matches")));
1502 sizeof(
int) * array_len);
1506 if (use_subpatterns)
1512 int so = pmatch[
i].rm_so;
1513 int eo = pmatch[
i].rm_eo;
1517 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)
1523 int so = pmatch[0].rm_so;
1524 int eo = pmatch[0].rm_eo;
1528 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)
1538 if (fetching_unmatched &&
1539 pmatch[0].rm_so >= 0 &&
1540 (pmatch[0].rm_so - prev_valid_match_end) > maxlen)
1541 maxlen = (pmatch[0].rm_so - prev_valid_match_end);
1542 prev_valid_match_end = pmatch[0].rm_eo;
1544 prev_match_end = pmatch[0].rm_eo;
1547 if (!re_flags->
glob)
1556 start_search = prev_match_end;
1557 if (pmatch[0].rm_so == pmatch[0].rm_eo)
1559 if (start_search > wide_len)
1567 if (fetching_unmatched &&
1568 (wide_len - prev_valid_match_end) > maxlen)
1569 maxlen = (wide_len - prev_valid_match_end);
1579 int64 maxsiz = eml * (int64) maxlen;
1592 if (maxsiz > orig_len)
1593 conv_bufsiz = orig_len + 1;
1595 conv_bufsiz = maxsiz + 1;
1624 bool *nulls = matchctx->
nulls;
1637 if (so < 0 || eo < 0)
1648 Assert(len < matchctx->conv_bufsiz);
1667 TEXTOID, -1,
false, TYPALIGN_INT);
1696 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1698 errmsg(
"%s does not support the \"global\" option",
1699 "regexp_split_to_table()")));
1701 re_flags.
glob =
true;
1751 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1753 errmsg(
"%s does not support the \"global\" option",
1754 "regexp_split_to_array()")));
1756 re_flags.
glob =
true;
1802 elog(
ERROR,
"invalid match ending position");
1806 elog(
ERROR,
"invalid match starting position");
1815 Assert(len < splitctx->conv_bufsiz);
1852 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1853 errmsg(
"invalid value for parameter \"%s\": %d",
1861 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1862 errmsg(
"invalid value for parameter \"%s\": %d",
1870 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1871 errmsg(
"invalid value for parameter \"%s\": %d",
1872 "subexpr", subexpr)));
1880 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1882 errmsg(
"%s does not support the \"global\" option",
1883 "regexp_substr()")));
1885 re_flags.
glob =
true;
1909 if (so < 0 || eo < 0)
1969 if (case_insensitive)
1993 pg_regerror(re_result, re, errMsg,
sizeof(errMsg));
1995 (
errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
1996 errmsg(
"regular expression failed: %s", errMsg)));
2002 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)
#define Assert(condition)
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)
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 AmcheckOptions opts
static XLogRecPtr startpos
static Datum PointerGetDatum(const void *X)
static Datum Int32GetDatum(int32 X)
MemoryContextSwitchTo(old_ctx)
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)