diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index a314ecc4fe..8f9d0211f8 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -3587,14 +3587,19 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, foreach(lc, *varinfos) { GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc); + AttrNumber attnum; Assert(varinfo->rel == rel); - if (IsA(varinfo->var, Var)) - { - attnums = bms_add_member(attnums, - ((Var *) varinfo->var)->varattno); - } + if (!IsA(varinfo->var, Var)) + continue; + + attnum = ((Var *) varinfo->var)->varattno; + + if (!AttrNumberIsForUserDefinedAttr(attnum)) + continue; + + attnums = bms_add_member(attnums, attnum); } /* look for the ndistinct statistics matching the most vars */ @@ -3674,6 +3679,10 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, } attnum = ((Var *) varinfo->var)->varattno; + + if (!AttrNumberIsForUserDefinedAttr(attnum)) + continue; + if (!bms_is_member(attnum, matched)) newlist = lappend(newlist, varinfo); } diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out index 4af61b4119..f827c8f2df 100644 --- a/src/test/regress/expected/stats_ext.out +++ b/src/test/regress/expected/stats_ext.out @@ -216,6 +216,13 @@ SELECT s.stxkind, d.stxdndistinct {d,f,m} | {"3, 4": 11, "3, 6": 11, "4, 6": 11, "3, 4, 6": 11} (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 SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); estimated | actual diff --git a/src/test/regress/sql/stats_ext.sql b/src/test/regress/sql/stats_ext.sql index 279158ff02..45ad265406 100644 --- a/src/test/regress/sql/stats_ext.sql +++ b/src/test/regress/sql/stats_ext.sql @@ -157,6 +157,9 @@ SELECT s.stxkind, d.stxdndistinct WHERE s.stxrelid = 'ndistinct'::regclass 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 SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b');