From: Alexander Lakhin <exclusion@gmail.com>
To: pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #16863: Assert failed in set_plain_rel_size() on processing ~* with a long prefix
Date: Fri, 12 Feb 2021 23:00:01 +0300
Message-ID: <6de0a0c3-ada9-cd0c-3e4e-2fa9964b41e3@gmail.com> (raw)
In-Reply-To: <16863-35bf75b1b5ee4032@postgresql.org>
References: <16863-35bf75b1b5ee4032@postgresql.org>
12.02.2021 22:00, PG Bug reporting form wrote:
> SELECT * FROM test WHERE t ~* ('^' || repeat('-', 500));
> ...
> #2 0x0000559da7963ff8 in ExceptionalCondition (
> conditionName=conditionName@entry=0x559da7ab4690 "rel->rows > 0 ||
> IS_DUMMY_REL(rel)",
> errorType=errorType@entry=0x559da79bf028 "FailedAssertion",
> fileName=fileName@entry=0x559da7ab43b1 "allpaths.c",
> lineNumber=lineNumber@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
Attachments:debug_sel.patch (text/x-patch, 1.6K) downloaddiff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.cindex e7a3e92bc20..726494bd98d 100644--- a/src/backend/optimizer/path/allpaths.c+++ b/src/backend/optimizer/path/allpaths.c@@ -459,6 +459,7 @@ set_rel_size(PlannerInfo *root, RelOptInfo *rel,
/*
* We insist that all non-dummy rels have a nonzero rowcount estimate.
*/
+elog(INFO, "rel->rows: %f", rel->rows);
Assert(rel->rows > 0 || IS_DUMMY_REL(rel));
}
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.cindex ffd2bf87834..3213522d5bc 100644--- a/src/backend/optimizer/path/costsize.c+++ b/src/backend/optimizer/path/costsize.c@@ -4658,6 +4658,7 @@ set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
NULL);
rel->rows = clamp_row_est(nrows);
+elog(INFO, "rel->rows: %f; nrows: %f", rel->rows, nrows);
cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.cindex bcfbaa1c3d1..aeb3a768692 100644--- a/src/backend/utils/adt/like_support.c+++ b/src/backend/utils/adt/like_support.c@@ -1443,8 +1443,10 @@ regex_selectivity(const char *patt, int pattlen, bool case_insensitive,
}
/* If there's a fixed prefix, discount its selectivity */
+elog(INFO, "sel: %0.400f, FIXED_CHAR_SEL: %f, fixed_prefix_len: %d, pow: %0.400f", sel, FIXED_CHAR_SEL, fixed_prefix_len, pow(FIXED_CHAR_SEL, fixed_prefix_len));
if (fixed_prefix_len > 0)
sel /= pow(FIXED_CHAR_SEL, fixed_prefix_len);
+elog(INFO, "sel: %f", sel);
/* Make sure result stays in range */
CLAMP_PROBABILITY(sel);
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: exclusion@gmail.com, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #16863: Assert failed in set_plain_rel_size() on processing ~* with a long prefix
In-Reply-To: <6de0a0c3-ada9-cd0c-3e4e-2fa9964b41e3@gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox