}
addchr(cv, cc);
}
- if (CANCEL_REQUESTED(v->re))
- {
- ERR(REG_CANCEL);
- return NULL;
- }
+ INTERRUPT(v->re);
}
return cv;
* compilation, since no code path will go very long without making a new
* state or arc.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return NULL;
- }
+ INTERRUPT(nfa->v->re);
/* first, recycle anything that's on the freelist */
if (nfa->freestates != NULL)
* compilation, since no code path will go very long without making a new
* state or arc.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return;
- }
+ INTERRUPT(nfa->v->re);
/* check for duplicate arc, using whichever chain is shorter */
if (from->nouts <= to->nins)
* Because we bypass newarc() in this code path, we'd better include a
* cancel check.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return;
- }
+ INTERRUPT(nfa->v->re);
sortins(nfa, oldState);
sortins(nfa, newState);
* Because we bypass newarc() in this code path, we'd better include a
* cancel check.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return;
- }
+ INTERRUPT(nfa->v->re);
sortins(nfa, oldState);
sortins(nfa, newState);
* Because we bypass newarc() in this code path, we'd better include a
* cancel check.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return;
- }
+ INTERRUPT(nfa->v->re);
/* Sort existing inarcs as well as proposed new ones */
sortins(nfa, s);
* Because we bypass newarc() in this code path, we'd better include a
* cancel check.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return;
- }
+ INTERRUPT(nfa->v->re);
sortouts(nfa, oldState);
sortouts(nfa, newState);
* Because we bypass newarc() in this code path, we'd better include a
* cancel check.
*/
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return;
- }
+ INTERRUPT(nfa->v->re);
sortouts(nfa, oldState);
sortouts(nfa, newState);
return false;
/* In case the search takes a long time, check for cancel */
- if (CANCEL_REQUESTED(nfa->v->re))
- {
- NERR(REG_CANCEL);
- return false;
- }
+ INTERRUPT(nfa->v->re);
/* Create a haspath array for this state */
haspath = (bool *) MALLOC((DUPINF + 2) * sizeof(bool));
int latype);
static void freelacons(struct subre *subs, int n);
static void rfree(regex_t *re);
-static int rcancelrequested(void);
static int rstacktoodeep(void);
#ifdef REG_DEBUG
/* static function list */
static const struct fns functions = {
rfree, /* regfree insides */
- rcancelrequested, /* check for cancel request */
rstacktoodeep /* check for stack getting dangerously deep */
};
}
}
-/*
- * rcancelrequested - check for external request to cancel regex operation
- *
- * Return nonzero to fail the operation with error code REG_CANCEL,
- * zero to keep going
- *
- * The current implementation is Postgres-specific. If we ever get around
- * to splitting the regex code out as a standalone library, there will need
- * to be some API to let applications define a callback function for this.
- */
-static int
-rcancelrequested(void)
-{
- return InterruptPending && (QueryCancelPending || ProcDiePending);
-}
-
/*
* rstacktoodeep - check for stack getting dangerously deep
*
* Checking for operation cancel in the inner text search loop seems
* unduly expensive. As a compromise, check during cache misses.
*/
- if (CANCEL_REQUESTED(v->re))
- {
- ERR(REG_CANCEL);
- return NULL;
- }
+ INTERRUPT(v->re);
/*
* What set of states would we end up in after consuming the co character?
MDEBUG(("%d: cdissect %c %ld-%ld\n", t->id, t->op, LOFF(begin), LOFF(end)));
/* handy place to check for operation cancel */
- if (CANCEL_REQUESTED(v->re))
- return REG_CANCEL;
+ INTERRUPT(v->re);
/* ... and stack overrun */
if (STACK_TOO_DEEP(v->re))
return REG_ETOOBIG;
{
char errMsg[100];
- /* See regexp.c for explanation */
- CHECK_FOR_INTERRUPTS();
pg_regerror(re_result, &re_tmp, errMsg, sizeof(errMsg));
ereturn(escontext, false,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
if (regcomp_result != REG_OKAY)
{
/* re didn't compile (no need for pg_regfree, if so) */
-
- /*
- * Here and in other places in this file, do CHECK_FOR_INTERRUPTS
- * before reporting a regex error. This is so that if the regex
- * library aborts and returns REG_CANCEL, we don't print an error
- * message that implies the regex was invalid.
- */
- CHECK_FOR_INTERRUPTS();
-
pg_regerror(regcomp_result, &re_temp.cre_re, errMsg, sizeof(errMsg));
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
if (regexec_result != REG_OKAY && regexec_result != REG_NOMATCH)
{
/* re failed??? */
- CHECK_FOR_INTERRUPTS();
pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
default:
/* re failed??? */
- CHECK_FOR_INTERRUPTS();
pg_regerror(re_result, re, errMsg, sizeof(errMsg));
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
{
char errMsg[100];
- CHECK_FOR_INTERRUPTS();
pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
#include "mb/pg_wchar.h"
-#include "miscadmin.h" /* needed by rcancelrequested/rstacktoodeep */
+#include "miscadmin.h" /* needed by stacktoodeep */
/* overrides for regguts.h definitions, if any */
#define MALLOC(n) palloc_extended((n), MCXT_ALLOC_NO_OOM)
#define FREE(p) pfree(VS(p))
#define REALLOC(p,n) repalloc_extended(VS(p),(n), MCXT_ALLOC_NO_OOM)
+#define INTERRUPT(re) CHECK_FOR_INTERRUPTS()
#define assert(x) Assert(x)
/* internal character type and related */
{
REG_ECOLORS, "REG_ECOLORS", "too many colors"
},
-
-{
- REG_CANCEL, "REG_CANCEL", "operation cancelled"
-},
#define REG_BADOPT 18 /* invalid embedded option */
#define REG_ETOOBIG 19 /* regular expression is too complex */
#define REG_ECOLORS 20 /* too many colors */
-#define REG_CANCEL 21 /* operation cancelled */
/* two specials for debugging and testing */
#define REG_ATOI 101 /* convert error-code name to number */
#define REG_ITOA 102 /* convert error-code number to name */
#define FREE(p) free(VS(p))
#endif
+/* interruption */
+#ifndef INTERRUPT
+#define INTERRUPT(re)
+#endif
+
/* want size of a char in bits, and max value in bounded quantifiers */
#ifndef _POSIX2_RE_DUP_MAX
#define _POSIX2_RE_DUP_MAX 255 /* normally from */
struct fns
{
void FUNCPTR(free, (regex_t *));
- int FUNCPTR(cancel_requested, (void));
int FUNCPTR(stack_too_deep, (void));
};
-#define CANCEL_REQUESTED(re) \
- ((*((struct fns *) (re)->re_fns)->cancel_requested) ())
-
#define STACK_TOO_DEEP(re) \
((*((struct fns *) (re)->re_fns)->stack_too_deep) ())
if (regcomp_result != REG_OKAY)
{
/* re didn't compile (no need for pg_regfree, if so) */
-
- /*
- * Here and in other places in this file, do CHECK_FOR_INTERRUPTS
- * before reporting a regex error. This is so that if the regex
- * library aborts and returns REG_CANCEL, we don't print an error
- * message that implies the regex was invalid.
- */
- CHECK_FOR_INTERRUPTS();
-
pg_regerror(regcomp_result, result_re, errMsg, sizeof(errMsg));
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),
if (regexec_result != REG_OKAY && regexec_result != REG_NOMATCH)
{
/* re failed??? */
- CHECK_FOR_INTERRUPTS();
pg_regerror(regexec_result, re, errMsg, sizeof(errMsg));
ereport(ERROR,
(errcode(ERRCODE_INVALID_REGULAR_EXPRESSION),