Skip to content

Commit ff64359

Browse files
committed
Draft
1 parent edf9e2c commit ff64359

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/backend/utils/adt/selfuncs.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3965,6 +3965,7 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
39653965
MVNDistinct *stats;
39663966
StatisticExtInfo *matched_info = NULL;
39673967
RangeTblEntry *rte = planner_rt_fetch(rel->relid, root);
3968+
List *statlist;
39683969

39693970
/* bail out immediately if the table has no extended statistics */
39703971
if (!rel->statlist)
@@ -3973,7 +3974,10 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
39733974
/* look for the ndistinct statistics object matching the most vars */
39743975
nmatches_vars = 0; /* we require at least two matches */
39753976
nmatches_exprs = 0;
3976-
foreach(lc, rel->statlist)
3977+
3978+
attempt:
3979+
statlist = list_copy(rel->statlist);
3980+
foreach(lc, statlist)
39773981
{
39783982
ListCell *lc2;
39793983
StatisticExtInfo *info = (StatisticExtInfo *) lfirst(lc);
@@ -4200,7 +4204,11 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
42004204
* statistics includes all combinations of attributes.
42014205
*/
42024206
if (!item)
4203-
elog(ERROR, "corrupt MVNDistinct entry");
4207+
{
4208+
statOid = InvalidOid;
4209+
statlist = list_delete_ptr(statlist, matched_info);
4210+
goto attempt;
4211+
}
42044212

42054213
/* Form the output varinfo list, keeping only unmatched ones */
42064214
foreach(lc, *varinfos)

src/test/regress/sql/stats_ext.sql

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,26 @@ SELECT statistics_name, most_common_vals FROM pg_stats_ext x
16831683
SELECT statistics_name, most_common_vals FROM pg_stats_ext_exprs x
16841684
WHERE tablename = 'stats_ext_tbl' ORDER BY ROW(x.*);
16851685

1686+
CREATE TABLE ext_linear(x int, y int, z int);
1687+
INSERT INTO ext_linear (x,y,z) SELECT gs%47,gs%71,gs%53
1688+
FROM generate_series(1,100) AS gs;
1689+
CREATE STATISTICS x_y_linear ON x,y,z FROM ext_linear
1690+
WITH (method = 'linear');
1691+
VACUUM ANALYZE ext_linear;
1692+
1693+
-- Statistics built with the 'linear' method don't have x,z combination:
1694+
-- don't complain, but not use this statistic slot.
1695+
SELECT check_estimated_rows('SELECT count(*) FROM ext_linear GROUP BY x,z;');
1696+
-- have statistic combination on (x,y) - get correct estimation.
1697+
SELECT check_estimated_rows('SELECT count(*) FROM ext_linear GROUP BY x,y;');
1698+
CREATE STATISTICS x_y_linear_1 ON x,z,y FROM ext_linear WITH (method = 'linear');
1699+
DROP STATISTICS x_y_linear;
1700+
VACUUM ANALYZE ext_linear;
1701+
-- TODO: Now we have right combination in the second statistic slot and use it
1702+
-- getting correct groups number estimation
1703+
SELECT check_estimated_rows('SELECT count(*) FROM ext_linear GROUP BY x,z;');
1704+
DROP TABLE ext_linear;
1705+
16861706
-- Tidy up
16871707
DROP OPERATOR <<< (int, int);
16881708
DROP FUNCTION op_leak(int, int);

0 commit comments

Comments
 (0)