Skip to content

Commit

Permalink
[#7241] ysql: Import 'Avoid divide-by-zero in regex_selectivity() wit…
Browse files Browse the repository at this point in the history
…h long fixed prefix.'

Summary:
Upstream commit was a28df6fa3041523f9a96cf0d3c3929f8bdc7c797

Commit message was:
```
Given a regex pattern with a very long fixed prefix (approaching 500
characters), the result of pow(FIXED_CHAR_SEL, fixed_prefix_len) can
underflow to zero.  Typically the preceding selectivity calculation
would have underflowed as well, so that we compute 0/0 and get NaN.
In released branches this leads to an assertion failure later on.
That doesn't happen in HEAD, for reasons I've not explored yet,
but it's surely still a bug.

To fix, just skip the division when the pow() result is zero, so
that we'll (most likely) return a zero selectivity estimate.  In
the edge cases where "sel" didn't yet underflow, perhaps this
isn't desirable, but I'm not sure that the case is worth spending
a lot of effort on.  The results of regex_selectivity_sub() are
barely worth the electrons they're written on anyway :-(

Per report from Alexander Lakhin.  Back-patch to all supported versions.

Discussion: https://postgr.es/m/[email protected]
```

Test Plan: Build yugabyte DB and run test suite via Jenkins

Reviewers: jason

Reviewed By: jason

Subscribers: yql

Differential Revision: https://phabricator.dev.yugabyte.com/D10628
  • Loading branch information
tedyu committed Feb 16, 2021
1 parent b3a083f commit df37a8f
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/postgres/src/backend/utils/adt/selfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6260,9 +6260,18 @@ regex_selectivity(const char *patt, int pattlen, bool case_insensitive,
sel *= FULL_WILDCARD_SEL;
}

/* If there's a fixed prefix, discount its selectivity */
/*
* If there's a fixed prefix, discount its selectivity. We have to be
* careful here since a very long prefix could result in pow's result
* underflowing to zero (in which case "sel" probably has as well).
*/
if (fixed_prefix_len > 0)
sel /= pow(FIXED_CHAR_SEL, fixed_prefix_len);
{
double prefixsel = pow(FIXED_CHAR_SEL, fixed_prefix_len);

if (prefixsel > 0.0)
sel /= prefixsel;
}

/* Make sure result stays in range */
CLAMP_PROBABILITY(sel);
Expand Down

0 comments on commit df37a8f

Please sign in to comment.