Fix ndistinct estimates with system attributes
authorTomas Vondra
Fri, 26 Mar 2021 21:34:53 +0000 (22:34 +0100)
committerTomas Vondra
Fri, 26 Mar 2021 21:40:00 +0000 (22:40 +0100)
When estimating the number of groups using extended statistics, the code
was discarding information about system attributes. This led to strange
situation that

    SELECT 1 FROM t GROUP BY ctid;

could have produced higher estimate (equal to pg_class.reltuples) than

    SELECT 1 FROM t GROUP BY a, b, ctid;

with extended statistics on (a,b). Fixed by retaining information about
the system attribute.

Backpatch all the way to 10, where extended statistics were introduced.

Author: Tomas Vondra
Backpatch-through: 10

src/backend/utils/adt/selfuncs.c
src/test/regress/expected/stats_ext.out

index 2fefa9162162617b9e2ed8951b8c5d025676a7dd..69a8b41f2a06dd58e60d31e4379653ccf84ce639 100644 (file)
@@ -3743,11 +3743,11 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
 
            attnum = ((Var *) varinfo->var)->varattno;
 
-           if (!AttrNumberIsForUserDefinedAttr(attnum))
+           if (AttrNumberIsForUserDefinedAttr(attnum) &&
+               bms_is_member(attnum, matched))
                continue;
 
-           if (!bms_is_member(attnum, matched))
-               newlist = lappend(newlist, varinfo);
+           newlist = lappend(newlist, varinfo);
        }
 
        *varinfos = newlist;
index f2a1863c7b180368fbc52320e604afa28d0f7f57..f7b351ec8e2b7584369bd42129e8e4f6a5bf96e7 100644 (file)
@@ -222,7 +222,7 @@ SELECT s.stxkind, d.stxdndistinct
 SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY ctid, a, b');
  estimated | actual 
 -----------+--------
-        11 |   1000
+      1000 |   1000
 (1 row)
 
 -- Hash Aggregate, thanks to estimates improved by the statistic