aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2019-11-16 01:17:15 +0100
committerTomas Vondra <tomas.vondra@postgresql.org>2019-11-16 01:17:15 +0100
commitd482f7f867b58bbd29f65a4471eca8c5b57a7da0 (patch)
treed6ed8e930c1975ca4407603d0dee6757c4b6951e /src
parent76cbfcdf3a0dff3f029ca079701418b861ce86c8 (diff)
downloadpostgresql-d482f7f867b58bbd29f65a4471eca8c5b57a7da0.tar.gz
postgresql-d482f7f867b58bbd29f65a4471eca8c5b57a7da0.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/selfuncs.c19
-rw-r--r--src/test/regress/expected/stats_ext.out7
-rw-r--r--src/test/regress/sql/stats_ext.sql3
3 files changed, 24 insertions, 5 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 35a8995f623..024f325eb02 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -3582,14 +3582,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 */
@@ -3669,6 +3674,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 b65228fa07a..dfbc41c390d 100644
--- a/src/test/regress/expected/stats_ext.out
+++ b/src/test/regress/expected/stats_ext.out
@@ -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}
(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 040ee97a1e5..6237fb25c20 100644
--- a/src/test/regress/sql/stats_ext.sql
+++ b/src/test/regress/sql/stats_ext.sql
@@ -167,6 +167,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');