mirror of
https://github.com/postgres/postgres.git
synced 2025-05-01 01:04:50 +03:00
Skip system attributes when applying mvdistinct stats
When estimating number of distinct groups, we failed to ignore system attributes when matching the group expressions to mvdistinct stats, causing failures like ERROR: negative bitmapset member not allowed Fix that by simply skipping anything that is not a regular attribute. Backpatch to PostgreSQL 10, where the extended stats were introduced. Bug: #16111 Reported-by: Tuomas Leikola Author: Tomas Vondra Backpatch-through: 10 Discussion: https://postgr.es/m/16111-687799584c3a7e73@postgresql.org
This commit is contained in:
parent
76cbfcdf3a
commit
d482f7f867
@ -3582,14 +3582,19 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
foreach(lc, *varinfos)
|
foreach(lc, *varinfos)
|
||||||
{
|
{
|
||||||
GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc);
|
GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc);
|
||||||
|
AttrNumber attnum;
|
||||||
|
|
||||||
Assert(varinfo->rel == rel);
|
Assert(varinfo->rel == rel);
|
||||||
|
|
||||||
if (IsA(varinfo->var, Var))
|
if (!IsA(varinfo->var, Var))
|
||||||
{
|
continue;
|
||||||
attnums = bms_add_member(attnums,
|
|
||||||
((Var *) varinfo->var)->varattno);
|
attnum = ((Var *) varinfo->var)->varattno;
|
||||||
}
|
|
||||||
|
if (!AttrNumberIsForUserDefinedAttr(attnum))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
attnums = bms_add_member(attnums, attnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look for the ndistinct statistics matching the most vars */
|
/* look for the ndistinct statistics matching the most vars */
|
||||||
@ -3669,6 +3674,10 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
attnum = ((Var *) varinfo->var)->varattno;
|
attnum = ((Var *) varinfo->var)->varattno;
|
||||||
|
|
||||||
|
if (!AttrNumberIsForUserDefinedAttr(attnum))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!bms_is_member(attnum, matched))
|
if (!bms_is_member(attnum, matched))
|
||||||
newlist = lappend(newlist, varinfo);
|
newlist = lappend(newlist, varinfo);
|
||||||
}
|
}
|
||||||
|
@ -233,6 +233,13 @@ SELECT s.stxkind, d.stxdndistinct
|
|||||||
{d,f,m} | {"3, 4": 11, "3, 6": 11, "4, 6": 11, "3, 4, 6": 11}
|
{d,f,m} | {"3, 4": 11, "3, 6": 11, "4, 6": 11, "3, 4, 6": 11}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- minor improvement, make sure the ctid does not break the matching
|
||||||
|
SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b');
|
||||||
|
estimated | actual
|
||||||
|
-----------+--------
|
||||||
|
11 | 1000
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- Hash Aggregate, thanks to estimates improved by the statistic
|
-- Hash Aggregate, thanks to estimates improved by the statistic
|
||||||
SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b');
|
SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b');
|
||||||
estimated | actual
|
estimated | actual
|
||||||
|
@ -167,6 +167,9 @@ SELECT s.stxkind, d.stxdndistinct
|
|||||||
WHERE s.stxrelid = 'ndistinct'::regclass
|
WHERE s.stxrelid = 'ndistinct'::regclass
|
||||||
AND d.stxoid = s.oid;
|
AND d.stxoid = s.oid;
|
||||||
|
|
||||||
|
-- minor improvement, make sure the ctid does not break the matching
|
||||||
|
SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b');
|
||||||
|
|
||||||
-- Hash Aggregate, thanks to estimates improved by the statistic
|
-- Hash Aggregate, thanks to estimates improved by the statistic
|
||||||
SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b');
|
SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b');
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user