PostgreSQL Source Code: src/backend/utils/adt/regexp.c File Reference (original) (raw)

Go to the source code of this file.

Data Structures
struct pg_re_flags
struct regexp_matches_ctx
struct cached_re_str
Typedefs
typedef struct pg_re_flags pg_re_flags
typedef struct regexp_matches_ctx regexp_matches_ctx
typedef struct cached_re_str cached_re_str
Functions
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)
static ArrayType * build_regexp_match_result (regexp_matches_ctx *matchctx)
static Datum build_regexp_split_result (regexp_matches_ctx *splitctx)
regex_t * RE_compile_and_cache (text *text_re, int cflags, Oid collation)
static bool RE_wchar_execute (regex_t *re, pg_wchar *data, int data_len, int start_search, int nmatch, regmatch_t *pmatch)
static bool RE_execute (regex_t *re, char *dat, int dat_len, int nmatch, regmatch_t *pmatch)
bool RE_compile_and_execute (text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)
static void parse_re_flags (pg_re_flags *flags, text *opts)
Datum nameregexeq (PG_FUNCTION_ARGS)
Datum nameregexne (PG_FUNCTION_ARGS)
Datum textregexeq (PG_FUNCTION_ARGS)
Datum textregexne (PG_FUNCTION_ARGS)
Datum nameicregexeq (PG_FUNCTION_ARGS)
Datum nameicregexne (PG_FUNCTION_ARGS)
Datum texticregexeq (PG_FUNCTION_ARGS)
Datum texticregexne (PG_FUNCTION_ARGS)
Datum textregexsubstr (PG_FUNCTION_ARGS)
Datum textregexreplace_noopt (PG_FUNCTION_ARGS)
Datum textregexreplace (PG_FUNCTION_ARGS)
Datum textregexreplace_extended (PG_FUNCTION_ARGS)
Datum textregexreplace_extended_no_n (PG_FUNCTION_ARGS)
Datum textregexreplace_extended_no_flags (PG_FUNCTION_ARGS)
static text * similar_escape_internal (text *pat_text, text *esc_text)
Datum similar_to_escape_2 (PG_FUNCTION_ARGS)
Datum similar_to_escape_1 (PG_FUNCTION_ARGS)
Datum similar_escape (PG_FUNCTION_ARGS)
Datum regexp_count (PG_FUNCTION_ARGS)
Datum regexp_count_no_start (PG_FUNCTION_ARGS)
Datum regexp_count_no_flags (PG_FUNCTION_ARGS)
Datum regexp_instr (PG_FUNCTION_ARGS)
Datum regexp_instr_no_start (PG_FUNCTION_ARGS)
Datum regexp_instr_no_n (PG_FUNCTION_ARGS)
Datum regexp_instr_no_endoption (PG_FUNCTION_ARGS)
Datum regexp_instr_no_flags (PG_FUNCTION_ARGS)
Datum regexp_instr_no_subexpr (PG_FUNCTION_ARGS)
Datum regexp_like (PG_FUNCTION_ARGS)
Datum regexp_like_no_flags (PG_FUNCTION_ARGS)
Datum regexp_match (PG_FUNCTION_ARGS)
Datum regexp_match_no_flags (PG_FUNCTION_ARGS)
Datum regexp_matches (PG_FUNCTION_ARGS)
Datum regexp_matches_no_flags (PG_FUNCTION_ARGS)
Datum regexp_split_to_table (PG_FUNCTION_ARGS)
Datum regexp_split_to_table_no_flags (PG_FUNCTION_ARGS)
Datum regexp_split_to_array (PG_FUNCTION_ARGS)
Datum regexp_split_to_array_no_flags (PG_FUNCTION_ARGS)
Datum regexp_substr (PG_FUNCTION_ARGS)
Datum regexp_substr_no_start (PG_FUNCTION_ARGS)
Datum regexp_substr_no_n (PG_FUNCTION_ARGS)
Datum regexp_substr_no_flags (PG_FUNCTION_ARGS)
Datum regexp_substr_no_subexpr (PG_FUNCTION_ARGS)
char * regexp_fixed_prefix (text *text_re, bool case_insensitive, Oid collation, bool *exact)
Variables
static MemoryContext RegexpCacheMemoryContext
static int num_res = 0
static cached_re_str re_array [MAX_CACHED_RES]

MAX_CACHED_RES

#define MAX_CACHED_RES 32

PG_GETARG_TEXT_PP_IF_EXISTS

cached_re_str

pg_re_flags

regexp_matches_ctx

build_regexp_match_result()

Definition at line 1620 of file regexp.c.

1621{

1624 bool *nulls = matchctx->nulls;

1625 int dims[1];

1626 int lbs[1];

1627 int loc;

1628 int i;

1629

1630

1633 {

1634 int so = matchctx->match_locs[loc++];

1635 int eo = matchctx->match_locs[loc++];

1636

1637 if (so < 0 || eo < 0)

1638 {

1639 elems[i] = (Datum) 0;

1640 nulls[i] = true;

1641 }

1642 else if (buf)

1643 {

1646 eo - so);

1647

1648 Assert(len < matchctx->conv_bufsiz);

1650 nulls[i] = false;

1651 }

1652 else

1653 {

1658 nulls[i] = false;

1659 }

1660 }

1661

1662

1664 lbs[0] = 1;

1665

1667 TEXTOID, -1, false, TYPALIGN_INT);

1668}

ArrayType * construct_md_array(Datum *elems, bool *nulls, int ndims, int *dims, int *lbs, Oid elmtype, int elmlen, bool elmbyval, char elmalign)

#define DirectFunctionCall3(func, arg1, arg2, arg3)

Assert(PointerIsAligned(start, uint64))

int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len)

static Datum PointerGetDatum(const void *X)

static Datum Int32GetDatum(int32 X)

Datum text_substr(PG_FUNCTION_ARGS)

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

References Assert(), buf, construct_md_array(), regexp_matches_ctx::conv_buf, cstring_to_text_with_len(), DirectFunctionCall3, regexp_matches_ctx::elems, i, Int32GetDatum(), len, regexp_matches_ctx::match_locs, regexp_matches_ctx::next_match, regexp_matches_ctx::npatterns, regexp_matches_ctx::nulls, regexp_matches_ctx::orig_str, pg_wchar2mb_with_len(), PointerGetDatum(), text_substr(), and regexp_matches_ctx::wide_str.

Referenced by regexp_match(), and regexp_matches().

build_regexp_split_result()

Definition at line 1791 of file regexp.c.

1792{

1796

1799 else

1802 elog(ERROR, "invalid match ending position");

1803

1806 elog(ERROR, "invalid match starting position");

1807

1808 if (buf)

1809 {

1810 int len;

1811

1815 Assert(len < splitctx->conv_bufsiz);

1817 }

1818 else

1819 {

1824 }

1825}

static XLogRecPtr startpos

References Assert(), buf, regexp_matches_ctx::conv_buf, cstring_to_text_with_len(), DirectFunctionCall3, elog, endpos, ERROR, Int32GetDatum(), len, regexp_matches_ctx::match_locs, regexp_matches_ctx::next_match, regexp_matches_ctx::orig_str, pg_wchar2mb_with_len(), PointerGetDatum(), startpos, text_substr(), and regexp_matches_ctx::wide_str.

Referenced by regexp_split_to_array(), and regexp_split_to_table().

nameicregexeq()

Definition at line 522 of file regexp.c.

523{

526

532 0, NULL));

533}

#define PG_GETARG_TEXT_PP(n)

#define PG_GETARG_NAME(n)

#define PG_GET_COLLATION()

#define PG_RETURN_BOOL(x)

bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch)

References NameStr, PG_GET_COLLATION, PG_GETARG_NAME, PG_GETARG_TEXT_PP, PG_RETURN_BOOL, RE_compile_and_execute(), REG_ADVANCED, and REG_ICASE.

nameicregexne()

nameregexeq()

nameregexne()

parse_re_flags()

Definition at line 385 of file regexp.c.

386{

387

389 flags->glob = false;

390

392 {

395 int i;

396

397 for (i = 0; i < opt_len; i++)

398 {

399 switch (opt_p[i])

400 {

401 case 'g':

402 flags->glob = true;

403 break;

404 case 'b':

406 break;

407 case 'c':

408 flags->cflags &= ~REG_ICASE;

409 break;

410 case 'e':

413 break;

414 case 'i':

416 break;

417 case 'm':

418 case 'n':

420 break;

421 case 'p':

423 flags->cflags &= ~REG_NLANCH;

424 break;

425 case 'q':

428 break;

429 case 's':

430 flags->cflags &= ~REG_NEWLINE;

431 break;

432 case 't':

433 flags->cflags &= ~REG_EXPANDED;

434 break;

435 case 'w':

436 flags->cflags &= ~REG_NLSTOP;

438 break;

439 case 'x':

441 break;

442 default:

444 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

445 errmsg("invalid regular expression option: \"%.*s\"",

447 break;

448 }

449 }

450 }

451}

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

int pg_mblen(const char *mbstr)

static AmcheckOptions opts

#define VARSIZE_ANY_EXHDR(PTR)

References pg_re_flags::cflags, ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, i, opts, pg_mblen(), REG_ADVANCED, REG_EXPANDED, REG_EXTENDED, REG_ICASE, REG_NEWLINE, REG_NLANCH, REG_NLSTOP, REG_QUOTE, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by regexp_count(), regexp_instr(), regexp_like(), regexp_match(), regexp_matches(), regexp_split_to_array(), regexp_split_to_table(), regexp_substr(), textregexreplace(), and textregexreplace_extended().

RE_compile_and_cache()

regex_t * RE_compile_and_cache ( text * text_re,
int cflags,
Oid collation
)

Definition at line 141 of file regexp.c.

142{

144 char *text_re_val = VARDATA_ANY(text_re);

146 int pattern_len;

147 int i;

148 int regcomp_result;

150 char errMsg[100];

152

153

154

155

156

157

159 {

160 if (re_array[i].cre_pat_len == text_re_len &&

161 re_array[i].cre_flags == cflags &&

162 re_array[i].cre_collation == collation &&

163 memcmp(re_array[i].cre_pat, text_re_val, text_re_len) == 0)

164 {

165

166

167

168 if (i > 0)

169 {

173 }

174

176 }

177 }

178

179

183 "RegexpCacheMemoryContext",

185

186

187

188

189

190

191

194 pattern,

195 text_re_len);

196

197

198

199

200

201

202

203

205 "RegexpMemoryContext",

208

210 pattern,

211 pattern_len,

212 cflags,

213 collation);

214

216

217 if (regcomp_result != REG_OKAY)

218 {

219

220 pg_regerror(regcomp_result, &re_temp.cre_re, errMsg, sizeof(errMsg));

222 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),

223 errmsg("invalid regular expression: %s", errMsg)));

224 }

225

226

228 memcpy(re_temp.cre_pat, text_re_val, text_re_len);

229

230

231

232

233

234 re_temp.cre_pat[text_re_len] = 0;

236

240

241

242

243

244

246 {

249

251 }

252

253

255

258

261

263

265}

int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)

void MemoryContextSetParent(MemoryContext context, MemoryContext new_parent)

void pfree(void *pointer)

MemoryContext TopMemoryContext

MemoryContext CurrentMemoryContext

void MemoryContextDelete(MemoryContext context)

void MemoryContextSetIdentifier(MemoryContext context, const char *id)

#define AllocSetContextCreate

#define ALLOCSET_SMALL_SIZES

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

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)

static MemoryContext RegexpCacheMemoryContext

static cached_re_str re_array[MAX_CACHED_RES]

MemoryContext cre_context

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, Assert(), cached_re_str::cre_collation, cached_re_str::cre_context, cached_re_str::cre_flags, cached_re_str::cre_pat, cached_re_str::cre_pat_len, cached_re_str::cre_re, CurrentMemoryContext, ereport, errcode(), errmsg(), ERROR, i, MAX_CACHED_RES, MemoryContextDelete(), MemoryContextSetIdentifier(), MemoryContextSetParent(), MemoryContextSwitchTo(), num_res, palloc(), pfree(), pg_mb2wchar_with_len(), pg_regcomp(), pg_regerror(), re_array, REG_OKAY, RegexpCacheMemoryContext, TopMemoryContext, unlikely, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by RE_compile_and_execute(), regexp_fixed_prefix(), replace_text_regexp(), setup_regexp_matches(), and textregexsubstr().

RE_compile_and_execute()

bool RE_compile_and_execute ( text * text_re,
char * dat,
int dat_len,
int cflags,
Oid collation,
int nmatch,
regmatch_t * pmatch
)

Definition at line 358 of file regexp.c.

361{

363

364

365 if (nmatch < 2)

367

368

370

371 return RE_execute(re, dat, dat_len, nmatch, pmatch);

372}

regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation)

static bool RE_execute(regex_t *re, char *dat, int dat_len, int nmatch, regmatch_t *pmatch)

References RE_compile_and_cache(), RE_execute(), REG_NOSUB, and regex_t.

Referenced by executeLikeRegex(), nameicregexeq(), nameicregexne(), nameregexeq(), nameregexne(), regexp_like(), texticregexeq(), texticregexne(), textregexeq(), and textregexne().

RE_execute()

static bool RE_execute ( regex_t * re, char * dat, int dat_len, int nmatch, regmatch_t * pmatch ) static

Definition at line 324 of file regexp.c.

326{

328 int data_len;

329 bool match;

330

331

334

335

337

339 return match;

340}

static bool RE_wchar_execute(regex_t *re, pg_wchar *data, int data_len, int start_search, int nmatch, regmatch_t *pmatch)

References data, palloc(), pfree(), pg_mb2wchar_with_len(), and RE_wchar_execute().

Referenced by RE_compile_and_execute(), and textregexsubstr().

RE_wchar_execute()

static bool RE_wchar_execute ( regex_t * re, pg_wchar * data, int data_len, int start_search, int nmatch, regmatch_t * pmatch ) static

Definition at line 282 of file regexp.c.

284{

285 int regexec_result;

286 char errMsg[100];

287

288

291 data_len,

292 start_search,

293 NULL,

294 nmatch,

295 pmatch,

296 0);

297

299 {

300

301 pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));

303 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),

304 errmsg("regular expression failed: %s", errMsg)));

305 }

306

307 return (regexec_result == REG_OKAY);

308}

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)

References data, ereport, errcode(), errmsg(), ERROR, pg_regerror(), pg_regexec(), REG_NOMATCH, and REG_OKAY.

Referenced by RE_execute(), and setup_regexp_matches().

regexp_count()

Definition at line 1066 of file regexp.c.

1067{

1074

1075

1077 {

1081 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1082 errmsg("invalid value for parameter \"%s\": %d",

1083 "start", start)));

1084 }

1085

1086

1088

1089 if (re_flags.glob)

1091 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1092

1093 errmsg("%s does not support the \"global\" option",

1094 "regexp_count()")));

1095

1096 re_flags.glob = true;

1097

1098

1101 false,

1102 false, false);

1103

1105}

#define PG_RETURN_INT32(x)

#define PG_GETARG_INT32(n)

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)

#define PG_GETARG_TEXT_PP_IF_EXISTS(_n)

static void parse_re_flags(pg_re_flags *flags, text *opts)

References ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, regexp_matches_ctx::nmatches, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_NARGS, PG_RETURN_INT32, setup_regexp_matches(), start, and str.

Referenced by regexp_count_no_flags(), and regexp_count_no_start().

regexp_count_no_flags()

regexp_count_no_start()

regexp_fixed_prefix()

char * regexp_fixed_prefix ( text * text_re,
bool case_insensitive,
Oid collation,
bool * exact
)

Definition at line 1953 of file regexp.c.

1955{

1956 char *result;

1958 int cflags;

1959 int re_result;

1961 size_t slen;

1962 size_t maxlen;

1963 char errMsg[100];

1964

1965 *exact = false;

1966

1967

1969 if (case_insensitive)

1971

1973

1974

1976

1977 switch (re_result)

1978 {

1980 return NULL;

1981

1983

1984 break;

1985

1987 *exact = true;

1988

1989 break;

1990

1991 default:

1992

1993 pg_regerror(re_result, re, errMsg, sizeof(errMsg));

1995 (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),

1996 errmsg("regular expression failed: %s", errMsg)));

1997 break;

1998 }

1999

2000

2002 result = (char *) palloc(maxlen);

2004 Assert(slen < maxlen);

2005

2007

2008 return result;

2009}

int pg_database_encoding_max_length(void)

int pg_regprefix(regex_t *re, chr **string, size_t *slength)

References Assert(), ereport, errcode(), errmsg(), ERROR, palloc(), pfree(), pg_database_encoding_max_length(), pg_regerror(), pg_regprefix(), pg_wchar2mb_with_len(), RE_compile_and_cache(), REG_ADVANCED, REG_EXACT, REG_ICASE, REG_NOMATCH, REG_NOSUB, REG_PREFIX, regex_t, and str.

Referenced by regex_fixed_prefix().

regexp_instr()

Definition at line 1126 of file regexp.c.

1127{

1131 int n = 1;

1132 int endoption = 0;

1134 int subexpr = 0;

1135 int pos;

1138

1139

1141 {

1145 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1146 errmsg("invalid value for parameter \"%s\": %d",

1147 "start", start)));

1148 }

1150 {

1152 if (n <= 0)

1154 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1155 errmsg("invalid value for parameter \"%s\": %d",

1156 "n", n)));

1157 }

1159 {

1161 if (endoption != 0 && endoption != 1)

1163 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1164 errmsg("invalid value for parameter \"%s\": %d",

1165 "endoption", endoption)));

1166 }

1168 {

1170 if (subexpr < 0)

1172 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1173 errmsg("invalid value for parameter \"%s\": %d",

1174 "subexpr", subexpr)));

1175 }

1176

1177

1179

1180 if (re_flags.glob)

1182 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1183

1184 errmsg("%s does not support the \"global\" option",

1185 "regexp_instr()")));

1186

1187 re_flags.glob = true;

1188

1189

1192 (subexpr > 0),

1193 false, false);

1194

1195

1198

1199

1200 if (subexpr > matchctx->npatterns)

1202

1203

1204 pos = (n - 1) * matchctx->npatterns;

1205 if (subexpr > 0)

1206 pos += subexpr - 1;

1207 pos *= 2;

1208 if (endoption == 1)

1209 pos += 1;

1210

1213 else

1215}

if(TABLE==NULL||TABLE_index==NULL)

References ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, if(), regexp_matches_ctx::match_locs, regexp_matches_ctx::nmatches, regexp_matches_ctx::npatterns, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_NARGS, PG_RETURN_INT32, setup_regexp_matches(), start, and str.

Referenced by regexp_instr_no_endoption(), regexp_instr_no_flags(), regexp_instr_no_n(), regexp_instr_no_start(), and regexp_instr_no_subexpr().

regexp_instr_no_endoption()

regexp_instr_no_flags()

regexp_instr_no_n()

regexp_instr_no_start()

regexp_instr_no_subexpr()

regexp_like()

Definition at line 1257 of file regexp.c.

1258{

1263

1264

1266

1267 if (re_flags.glob)

1269 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1270

1271 errmsg("%s does not support the \"global\" option",

1272 "regexp_like()")));

1273

1274

1280 0, NULL));

1281}

References pg_re_flags::cflags, ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_RETURN_BOOL, RE_compile_and_execute(), str, VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by regexp_like_no_flags().

regexp_like_no_flags()

regexp_match()

Definition at line 1295 of file regexp.c.

1296{

1302

1303

1305

1306 if (re_flags.glob)

1308 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1309

1310 errmsg("%s does not support the \"global\" option",

1311 "regexp_match()"),

1312 errhint("Use the regexp_matches function instead.")));

1313

1316

1317 if (matchctx->nmatches == 0)

1319

1321

1322

1325

1327}

int errhint(const char *fmt,...)

#define PG_RETURN_DATUM(x)

static ArrayType * build_regexp_match_result(regexp_matches_ctx *matchctx)

References Assert(), build_regexp_match_result(), regexp_matches_ctx::elems, ereport, errcode(), errhint(), errmsg(), ERROR, pg_re_flags::glob, regexp_matches_ctx::nmatches, regexp_matches_ctx::npatterns, regexp_matches_ctx::nulls, palloc(), parse_re_flags(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_RETURN_DATUM, PG_RETURN_NULL, PointerGetDatum(), and setup_regexp_matches().

Referenced by regexp_match_no_flags().

regexp_match_no_flags()

regexp_matches()

Definition at line 1341 of file regexp.c.

1342{

1345

1347 {

1352

1355

1356

1358

1359

1361 &re_flags, 0,

1363 true, false, false);

1364

1365

1368

1371 }

1372

1375

1377 {

1379

1383 }

1384

1386}

#define PG_GETARG_TEXT_P_COPY(n)

#define SRF_IS_FIRSTCALL()

#define SRF_PERCALL_SETUP()

#define SRF_RETURN_NEXT(_funcctx, _result)

#define SRF_FIRSTCALL_INIT()

#define SRF_RETURN_DONE(_funcctx)

MemoryContext multi_call_memory_ctx

References build_regexp_match_result(), regexp_matches_ctx::elems, if(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, regexp_matches_ctx::next_match, regexp_matches_ctx::nmatches, regexp_matches_ctx::npatterns, regexp_matches_ctx::nulls, palloc(), parse_re_flags(), PG_GET_COLLATION, PG_GETARG_TEXT_P_COPY, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PointerGetDatum(), setup_regexp_matches(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, and FuncCallContext::user_fctx.

Referenced by regexp_matches_no_flags().

regexp_matches_no_flags()

regexp_split_to_array()

Definition at line 1740 of file regexp.c.

1741{

1745

1746

1748

1749 if (re_flags.glob)

1751 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1752

1753 errmsg("%s does not support the \"global\" option",

1754 "regexp_split_to_array()")));

1755

1756 re_flags.glob = true;

1757

1760 &re_flags, 0,

1762 false, true, true);

1763

1765 {

1768 false,

1769 TEXTOID,

1772 }

1773

1775}

ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)

Datum makeArrayResult(ArrayBuildState *astate, MemoryContext rcontext)

static Datum build_regexp_split_result(regexp_matches_ctx *splitctx)

References accumArrayResult(), build_regexp_split_result(), CurrentMemoryContext, ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, makeArrayResult(), regexp_matches_ctx::next_match, regexp_matches_ctx::nmatches, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_RETURN_DATUM, and setup_regexp_matches().

Referenced by regexp_split_to_array_no_flags().

regexp_split_to_array_no_flags()

regexp_split_to_table()

Definition at line 1676 of file regexp.c.

1677{

1680

1682 {

1687

1690

1691

1693

1694 if (re_flags.glob)

1696 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1697

1698 errmsg("%s does not support the \"global\" option",

1699 "regexp_split_to_table()")));

1700

1701 re_flags.glob = true;

1702

1703

1705 &re_flags, 0,

1707 false, true, true);

1708

1711 }

1712

1715

1717 {

1719

1722 }

1723

1725}

References build_regexp_split_result(), ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, if(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, regexp_matches_ctx::next_match, regexp_matches_ctx::nmatches, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_TEXT_P_COPY, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, setup_regexp_matches(), SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, and FuncCallContext::user_fctx.

Referenced by regexp_split_to_table_no_flags().

regexp_split_to_table_no_flags()

regexp_substr()

Definition at line 1832 of file regexp.c.

1833{

1837 int n = 1;

1839 int subexpr = 0;

1840 int so,

1841 eo,

1842 pos;

1845

1846

1848 {

1852 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1853 errmsg("invalid value for parameter \"%s\": %d",

1854 "start", start)));

1855 }

1857 {

1859 if (n <= 0)

1861 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1862 errmsg("invalid value for parameter \"%s\": %d",

1863 "n", n)));

1864 }

1866 {

1868 if (subexpr < 0)

1870 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1871 errmsg("invalid value for parameter \"%s\": %d",

1872 "subexpr", subexpr)));

1873 }

1874

1875

1877

1878 if (re_flags.glob)

1880 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

1881

1882 errmsg("%s does not support the \"global\" option",

1883 "regexp_substr()")));

1884

1885 re_flags.glob = true;

1886

1887

1890 (subexpr > 0),

1891 false, false);

1892

1893

1896

1897

1898 if (subexpr > matchctx->npatterns)

1900

1901

1902 pos = (n - 1) * matchctx->npatterns;

1903 if (subexpr > 0)

1904 pos += subexpr - 1;

1905 pos *= 2;

1908

1909 if (so < 0 || eo < 0)

1911

1916}

References DirectFunctionCall3, ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, if(), Int32GetDatum(), regexp_matches_ctx::match_locs, regexp_matches_ctx::nmatches, regexp_matches_ctx::npatterns, regexp_matches_ctx::orig_str, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_NARGS, PG_RETURN_DATUM, PG_RETURN_NULL, PointerGetDatum(), setup_regexp_matches(), start, str, and text_substr().

Referenced by regexp_substr_no_flags(), regexp_substr_no_n(), regexp_substr_no_start(), and regexp_substr_no_subexpr().

regexp_substr_no_flags()

regexp_substr_no_n()

regexp_substr_no_start()

regexp_substr_no_subexpr()

setup_regexp_matches()

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 ) static

Definition at line 1416 of file regexp.c.

1422{

1425 int orig_len;

1427 int wide_len;

1428 int cflags;

1431 int pmatch_len;

1432 int array_len;

1433 int array_idx;

1434 int prev_match_end;

1435 int prev_valid_match_end;

1436 int maxlen = 0;

1437

1438

1439 matchctx->orig_str = orig_str;

1440

1441

1445

1446

1447 cflags = re_flags->cflags;

1448 if (!use_subpatterns)

1451

1452

1453 if (use_subpatterns && cpattern->re_nsub > 0)

1454 {

1455 matchctx->npatterns = cpattern->re_nsub;

1456 pmatch_len = cpattern->re_nsub + 1;

1457 }

1458 else

1459 {

1460 use_subpatterns = false;

1462 pmatch_len = 1;

1463 }

1464

1465

1467

1468

1469

1470

1471

1472

1473

1474 array_len = re_flags->glob ? 255 : 31;

1475 matchctx->match_locs = (int *) palloc(sizeof(int) * array_len);

1476 array_idx = 0;

1477

1478

1479 prev_match_end = 0;

1480 prev_valid_match_end = 0;

1481 while (RE_wchar_execute(cpattern, wide_str, wide_len, start_search,

1482 pmatch_len, pmatch))

1483 {

1484

1485

1486

1487

1488

1489 if (!ignore_degenerate ||

1490 (pmatch[0].rm_so < wide_len &&

1491 pmatch[0].rm_eo > prev_match_end))

1492 {

1493

1494 while (array_idx + matchctx->npatterns * 2 + 1 > array_len)

1495 {

1496 array_len += array_len + 1;

1499 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),

1500 errmsg("too many regular expression matches")));

1502 sizeof(int) * array_len);

1503 }

1504

1505

1506 if (use_subpatterns)

1507 {

1508 int i;

1509

1511 {

1512 int so = pmatch[i].rm_so;

1513 int eo = pmatch[i].rm_eo;

1514

1515 matchctx->match_locs[array_idx++] = so;

1516 matchctx->match_locs[array_idx++] = eo;

1517 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)

1518 maxlen = (eo - so);

1519 }

1520 }

1521 else

1522 {

1523 int so = pmatch[0].rm_so;

1524 int eo = pmatch[0].rm_eo;

1525

1526 matchctx->match_locs[array_idx++] = so;

1527 matchctx->match_locs[array_idx++] = eo;

1528 if (so >= 0 && eo >= 0 && (eo - so) > maxlen)

1529 maxlen = (eo - so);

1530 }

1532

1533

1534

1535

1536

1537

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;

1543 }

1544 prev_match_end = pmatch[0].rm_eo;

1545

1546

1547 if (!re_flags->glob)

1548 break;

1549

1550

1551

1552

1553

1554

1555

1556 start_search = prev_match_end;

1557 if (pmatch[0].rm_so == pmatch[0].rm_eo)

1558 start_search++;

1559 if (start_search > wide_len)

1560 break;

1561 }

1562

1563

1564

1565

1566

1567 if (fetching_unmatched &&

1568 (wide_len - prev_valid_match_end) > maxlen)

1569 maxlen = (wide_len - prev_valid_match_end);

1570

1571

1572

1573

1574

1575 matchctx->match_locs[array_idx] = wide_len;

1576

1577 if (eml > 1)

1578 {

1579 int64 maxsiz = eml * (int64) maxlen;

1580 int conv_bufsiz;

1581

1582

1583

1584

1585

1586

1587

1588

1589

1590

1591

1592 if (maxsiz > orig_len)

1593 conv_bufsiz = orig_len + 1;

1594 else

1595 conv_bufsiz = maxsiz + 1;

1596

1599 matchctx->wide_str = wide_str;

1600 }

1601 else

1602 {

1603

1604 pfree(wide_str);

1608 }

1609

1610

1612

1613 return matchctx;

1614}

void * repalloc(void *pointer, Size size)

void * palloc0(Size size)

References pg_re_flags::cflags, regexp_matches_ctx::conv_buf, regexp_matches_ctx::conv_bufsiz, ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, i, regexp_matches_ctx::match_locs, MaxAllocSize, regexp_matches_ctx::nmatches, regexp_matches_ctx::npatterns, regexp_matches_ctx::orig_str, palloc(), palloc0(), pfree(), pg_database_encoding_max_length(), pg_mb2wchar_with_len(), RE_compile_and_cache(), RE_wchar_execute(), REG_NOSUB, regex_t, regmatch_t, repalloc(), VARDATA_ANY, VARSIZE_ANY_EXHDR, and regexp_matches_ctx::wide_str.

Referenced by regexp_count(), regexp_instr(), regexp_match(), regexp_matches(), regexp_split_to_array(), regexp_split_to_table(), and regexp_substr().

similar_escape()

similar_escape_internal()

static text * similar_escape_internal ( text * pat_text, text * esc_text ) static

Definition at line 767 of file regexp.c.

768{

769 text *result;

770 char *p,

771 *e,

772 *r;

773 int plen,

774 elen;

775 bool afterescape = false;

776 bool incharclass = false;

777 int nquotes = 0;

778

781 if (esc_text == NULL)

782 {

783

784 e = "\\";

785 elen = 1;

786 }

787 else

788 {

791 if (elen == 0)

792 e = NULL;

793 else if (elen > 1)

794 {

796

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.")));

802 }

803 }

804

805

806

807

808

809

810

811

812

813

814

815

816

817

818

819

820

821

822

823

824

825

826

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

842

843

846

847 *r++ = '^';

848 *r++ = '(';

849 *r++ = '?';

850 *r++ = ':';

851

852 while (plen > 0)

853 {

854 char pchar = *p;

855

856

857

858

859

860

861

862

863

864

865

866

867 if (elen > 1)

868 {

870

871 if (mblen > 1)

872 {

873

874 if (afterescape)

875 {

876 *r++ = '\\';

877 memcpy(r, p, mblen);

878 r += mblen;

879 afterescape = false;

880 }

881 else if (e && elen == mblen && memcmp(e, p, mblen) == 0)

882 {

883

884 afterescape = true;

885 }

886 else

887 {

888

889

890

891

892

893 memcpy(r, p, mblen);

894 r += mblen;

895 }

896

897 p += mblen;

898 plen -= mblen;

899

900 continue;

901 }

902 }

903

904

905 if (afterescape)

906 {

907 if (pchar == '"' && !incharclass)

908 {

909

910 if (nquotes == 0)

911 {

912 *r++ = ')';

913 *r++ = '{';

914 *r++ = '1';

915 *r++ = ',';

916 *r++ = '1';

917 *r++ = '}';

918 *r++ = '?';

919 *r++ = '(';

920 }

921 else if (nquotes == 1)

922 {

923 *r++ = ')';

924 *r++ = '{';

925 *r++ = '1';

926 *r++ = ',';

927 *r++ = '1';

928 *r++ = '}';

929 *r++ = '(';

930 *r++ = '?';

931 *r++ = ':';

932 }

933 else

935 (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER),

936 errmsg("SQL regular expression may not contain more than two escape-double-quote separators")));

937 nquotes++;

938 }

939 else

940 {

941

942

943

944

945

946 *r++ = '\\';

947 *r++ = pchar;

948 }

949 afterescape = false;

950 }

951 else if (e && pchar == *e)

952 {

953

954 afterescape = true;

955 }

956 else if (incharclass)

957 {

958 if (pchar == '\\')

959 *r++ = '\\';

960 *r++ = pchar;

961 if (pchar == ']')

962 incharclass = false;

963 }

964 else if (pchar == '[')

965 {

966 *r++ = pchar;

967 incharclass = true;

968 }

969 else if (pchar == '%')

970 {

971 *r++ = '.';

972 *r++ = '*';

973 }

974 else if (pchar == '_')

975 *r++ = '.';

976 else if (pchar == '(')

977 {

978

979 *r++ = '(';

980 *r++ = '?';

981 *r++ = ':';

982 }

983 else if (pchar == '\\' || pchar == '.' ||

984 pchar == '^' || pchar == '$')

985 {

986 *r++ = '\\';

987 *r++ = pchar;

988 }

989 else

990 *r++ = pchar;

991 p++, plen--;

992 }

993

994 *r++ = ')';

995 *r++ = '$';

996

997 SET_VARSIZE(result, r - ((char *) result));

998

999 return result;

1000}

int pg_mbstrlen_with_len(const char *mbstr, int limit)

#define SET_VARSIZE(PTR, len)

References ereport, errcode(), errhint(), errmsg(), ERROR, palloc(), pg_mblen(), pg_mbstrlen_with_len(), SET_VARSIZE, VARDATA, VARDATA_ANY, VARHDRSZ, and VARSIZE_ANY_EXHDR.

Referenced by similar_escape(), similar_to_escape_1(), and similar_to_escape_2().

similar_to_escape_1()

similar_to_escape_2()

texticregexeq()

texticregexne()

textregexeq()

textregexne()

textregexreplace()

Definition at line 658 of file regexp.c.

659{

665

666

667

668

669

670

671

672

674 {

676

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.")));

683 }

684

686

689 0, flags.glob ? 0 : 1));

690}

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

References pg_re_flags::cflags, ereport, errcode(), errhint(), errmsg(), ERROR, pg_re_flags::glob, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, pg_mblen(), PG_RETURN_TEXT_P, replace_text_regexp(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by execute_extension_script().

textregexreplace_extended()

Definition at line 699 of file regexp.c.

700{

705 int n = 1;

708

709

711 {

715 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

716 errmsg("invalid value for parameter \"%s\": %d",

717 "start", start)));

718 }

720 {

722 if (n < 0)

724 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

725 errmsg("invalid value for parameter \"%s\": %d",

726 "n", n)));

727 }

728

729

731

732

734 n = re_flags.glob ? 0 : 1;

735

736

740}

References pg_re_flags::cflags, ereport, errcode(), errmsg(), ERROR, pg_re_flags::glob, parse_re_flags(), PG_GET_COLLATION, PG_GETARG_INT32, PG_GETARG_TEXT_PP, PG_GETARG_TEXT_PP_IF_EXISTS, PG_NARGS, PG_RETURN_TEXT_P, replace_text_regexp(), and start.

Referenced by textregexreplace_extended_no_flags(), and textregexreplace_extended_no_n().

textregexreplace_extended_no_flags()

textregexreplace_extended_no_n()

textregexreplace_noopt()

textregexsubstr()

Definition at line 583 of file regexp.c.

584{

589 int so,

590 eo;

591

592

594

595

596

597

598

599

600

603 2, pmatch))

605

606 if (re->re_nsub > 0)

607 {

608

609 so = pmatch[1].rm_so;

610 eo = pmatch[1].rm_eo;

611 }

612 else

613 {

614

615 so = pmatch[0].rm_so;

616 eo = pmatch[0].rm_eo;

617 }

618

619

620

621

622

623

624

625 if (so < 0 || eo < 0)

627

632}

References DirectFunctionCall3, Int32GetDatum(), PG_GET_COLLATION, PG_GETARG_TEXT_PP, PG_RETURN_NULL, PointerGetDatum(), RE_compile_and_cache(), RE_execute(), REG_ADVANCED, regex_t, regmatch_t, text_substr(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

num_res

re_array

RegexpCacheMemoryContext