mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +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
bc049d0d46
commit
25a9ff6cad
@ -3931,14 +3931,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 */
|
||||||
@ -4018,6 +4023,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);
|
||||||
}
|
}
|
||||||
|
@ -217,6 +217,18 @@ SELECT stxkind, stxndistinct
|
|||||||
{d,f} | {"3, 4": 301, "3, 6": 301, "4, 6": 301, "3, 4, 6": 301}
|
{d,f} | {"3, 4": 301, "3, 6": 301, "4, 6": 301, "3, 4, 6": 301}
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- minor improvement, make sure the ctid does not break the matching
|
||||||
|
EXPLAIN (COSTS off)
|
||||||
|
SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b;
|
||||||
|
QUERY PLAN
|
||||||
|
-----------------------------------
|
||||||
|
GroupAggregate
|
||||||
|
Group Key: ctid, a, b
|
||||||
|
-> Sort
|
||||||
|
Sort Key: ctid, a, b
|
||||||
|
-> Seq Scan on ndistinct
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
-- Hash Aggregate, thanks to estimates improved by the statistic
|
-- Hash Aggregate, thanks to estimates improved by the statistic
|
||||||
EXPLAIN (COSTS off)
|
EXPLAIN (COSTS off)
|
||||||
SELECT COUNT(*) FROM ndistinct GROUP BY a, b;
|
SELECT COUNT(*) FROM ndistinct GROUP BY a, b;
|
||||||
|
@ -144,6 +144,10 @@ ANALYZE ndistinct;
|
|||||||
SELECT stxkind, stxndistinct
|
SELECT stxkind, stxndistinct
|
||||||
FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass;
|
FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass;
|
||||||
|
|
||||||
|
-- minor improvement, make sure the ctid does not break the matching
|
||||||
|
EXPLAIN (COSTS off)
|
||||||
|
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
|
||||||
EXPLAIN (COSTS off)
|
EXPLAIN (COSTS off)
|
||||||
SELECT COUNT(*) FROM ndistinct GROUP BY a, b;
|
SELECT COUNT(*) FROM ndistinct GROUP BY a, b;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user