Re: BUG #16863: Assert failed in set_plain_rel_size() on processing ~* with a long prefix

From: Alexander Lakhin <exclusion(at)gmail(dot)com>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #16863: Assert failed in set_plain_rel_size() on processing ~* with a long prefix
Date: 2021-02-12 20:00:01
Message-ID: 6de0a0c3-ada9-cd0c-3e4e-2fa9964b41e3@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

12.02.2021 22:00, PG Bug reporting form wrote:
> SELECT * FROM test WHERE t ~* ('^' || repeat('-', 500));
> ...
> #2 0x0000559da7963ff8 in ExceptionalCondition (
> conditionName=conditionName(at)entry=0x559da7ab4690 "rel->rows > 0 ||
> IS_DUMMY_REL(rel)",
> errorType=errorType(at)entry=0x559da79bf028 "FailedAssertion",
> fileName=fileName(at)entry=0x559da7ab43b1 "allpaths.c",
> lineNumber=lineNumber(at)entry=462) at assert.c:67
With the attached debugging patch applied I see that rel->rows there is
NaN. At the end of the walk by the following calls:
set_plain_rel_size -> set_baserel_size_estimates ->
clauselist_selectivity -> clauselist_selectivity_simple ->
clause_selectivity -> restriction_selectivity -> icregexeqsel ->
patternsel -> patternsel_common -> pattern_fixed_prefix ->
regex_fixed_prefix -> regex_selectivity
I've found a division that produces NaN:
sel /= pow(FIXED_CHAR_SEL, fixed_prefix_len);

The complete output with the debugging code:
psql:500.sql:2: INFO:  sel:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
FIXED_CHAR_SEL: 0.200000, fixed_prefix_len: 500, pow:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
psql:500.sql:2: INFO:  sel: NaN
psql:500.sql:2: INFO:  rel->rows: NaN; nrows: NaN
psql:500.sql:2: INFO:  rel->rows: NaN
psql:500.sql:2: server closed the connection unexpectedly

With the prefix length 400 the output is different:
psql:400.sql:2: INFO:  sel:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002582249878086965166223199366465225696632326517795503118666931124080740300000000000000000000000000000000000000000000000000,
FIXED_CHAR_SEL: 0.200000, fixed_prefix_len: 400, pow:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002582249878086966144821031402096464952544460966116815567078211594740854000000000000000000000000000000000000000000000000000
psql:400.sql:2: INFO:  sel: 1.000000
psql:400.sql:2: INFO:  rel->rows: 7.000000; nrows: 6.800000
psql:400.sql:2: INFO:  rel->rows: 7.000000

On the master with the length 500 there is no assertion failure but the
row count is strange:
psql:master500.sql:3: INFO:  sel:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,
FIXED_CHAR_SEL: 0.200000, fixed_prefix_len: 500, pow:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
psql:master500.sql:3: INFO:  sel: NaN
psql:master500.sql:3: INFO:  rel->rows:
10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104.000000;
nrows: NaN
psql:master500.sql:3: INFO:  rel->rows:
10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104.000000

By the way, if the following check in restriction_selectivity() is
intended to throw error on an invalid selectivity, shouldn't the
isnan(result) test be appended here?:
    if (result < 0.0 || result > 1.0)
        elog(ERROR, "invalid restriction selectivity: %f", result);

Best regards,
Alexander

Attachment Content-Type Size
debug_sel.patch text/x-patch 1.6 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message David Zhang 2021-02-12 20:03:56 Re: [BUG] Autovacuum not dynamically decreasing cost_limit and cost_delay
Previous Message PG Bug reporting form 2021-02-12 19:00:01 BUG #16863: Assert failed in set_plain_rel_size() on processing ~* with a long prefix