diff options
author | Tom Lane | 2014-03-01 20:20:56 +0000 |
---|---|---|
committer | Tom Lane | 2014-03-01 20:20:56 +0000 |
commit | 9662143f0c35d64d7042fbeaf879df8f0b54be32 (patch) | |
tree | e352c3468320e15d1a0e029558e84b47b4ac48c1 /src/backend/regex/regcomp.c | |
parent | d8a42b150fa83de0a058843a4d9d61af3d98e333 (diff) |
Allow regex operations to be terminated early by query cancel requests.
The regex code didn't have any provision for query cancel; which is
unsurprising given its non-Postgres origin, but still problematic since
some operations can take a long time. Introduce a callback function to
check for a pending query cancel or session termination request, and
call it in a couple of strategic spots where we can make the regex code
exit with an error indicator.
If we ever actually split out the regex code as a standalone library,
some additional work will be needed to let the cancel callback function
be specified externally to the library. But that's straightforward
(certainly so by comparison to putting the locale-dependent character
classification logic on a similar arms-length basis), and there seems
no need to do it right now.
A bigger issue is that there may be more places than these two where
we need to check for cancels. We can always add more checks later,
now that the infrastructure is in place.
Since there are known examples of not-terribly-long regexes that can
lock up a backend for a long time, back-patch to all supported branches.
I have hopes of fixing the known performance problems later, but adding
query cancel ability seems like a good idea even if they were all fixed.
Diffstat (limited to 'src/backend/regex/regcomp.c')
-rw-r--r-- | src/backend/regex/regcomp.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index ca1ccc52023..d31d7f7b727 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -34,6 +34,8 @@ #include "regex/regguts.h" +#include "miscadmin.h" /* needed by rcancelrequested() */ + /* * forward declarations, up here so forward datatypes etc. are defined early */ @@ -67,6 +69,7 @@ static long nfanode(struct vars *, struct subre *, FILE *); static int newlacon(struct vars *, struct state *, struct state *, int); static void freelacons(struct subre *, int); static void rfree(regex_t *); +static int rcancelrequested(void); #ifdef REG_DEBUG static void dump(regex_t *, FILE *); @@ -276,6 +279,7 @@ struct vars /* static function list */ static const struct fns functions = { rfree, /* regfree insides */ + rcancelrequested /* check for cancel request */ }; @@ -1893,6 +1897,22 @@ rfree(regex_t *re) } } +/* + * 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); +} + #ifdef REG_DEBUG /* |