mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-07 03:53:23 +02:00
Fix planner failure with extended statistics on partitioned tables.
Some cases would result in "cache lookup failed for statistics object", due to trying to fetch inherited statistics when only non-inherited ones are available or vice versa. Richard Guo and Justin Pryzby Discussion: https://postgr.es/m/20221030170520.GM16921@telsasoft.com
This commit is contained in:
parent
8b0a5cf3fe
commit
1f1865e908
@ -3912,7 +3912,7 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
Oid statOid = InvalidOid;
|
Oid statOid = InvalidOid;
|
||||||
MVNDistinct *stats;
|
MVNDistinct *stats;
|
||||||
StatisticExtInfo *matched_info = NULL;
|
StatisticExtInfo *matched_info = NULL;
|
||||||
RangeTblEntry *rte;
|
RangeTblEntry *rte = planner_rt_fetch(rel->relid, root);
|
||||||
|
|
||||||
/* bail out immediately if the table has no extended statistics */
|
/* bail out immediately if the table has no extended statistics */
|
||||||
if (!rel->statlist)
|
if (!rel->statlist)
|
||||||
@ -3932,6 +3932,10 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
if (info->kind != STATS_EXT_NDISTINCT)
|
if (info->kind != STATS_EXT_NDISTINCT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* skip statistics with mismatching stxdinherit value */
|
||||||
|
if (info->inherit != rte->inh)
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine how many expressions (and variables in non-matched
|
* Determine how many expressions (and variables in non-matched
|
||||||
* expressions) match. We'll then use these numbers to pick the
|
* expressions) match. We'll then use these numbers to pick the
|
||||||
@ -4003,7 +4007,6 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
|
|||||||
|
|
||||||
Assert(nmatches_vars + nmatches_exprs > 1);
|
Assert(nmatches_vars + nmatches_exprs > 1);
|
||||||
|
|
||||||
rte = planner_rt_fetch(rel->relid, root);
|
|
||||||
stats = statext_ndistinct_load(statOid, rte->inh);
|
stats = statext_ndistinct_load(statOid, rte->inh);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5240,6 +5243,10 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
|
|||||||
if (info->kind != STATS_EXT_EXPRESSIONS)
|
if (info->kind != STATS_EXT_EXPRESSIONS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* skip stats with mismatching stxdinherit value */
|
||||||
|
if (info->inherit != rte->inh)
|
||||||
|
continue;
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
foreach(expr_item, info->exprs)
|
foreach(expr_item, info->exprs)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +232,7 @@ DROP TABLE stxdinh, stxdinh1, stxdinh2;
|
|||||||
CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i);
|
CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i);
|
||||||
CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100);
|
CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100);
|
||||||
INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a;
|
INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a;
|
||||||
CREATE STATISTICS stxdinp ON a, b FROM stxdinp;
|
CREATE STATISTICS stxdinp ON (a + 1), a, b FROM stxdinp;
|
||||||
VACUUM ANALYZE stxdinp; -- partitions are processed recursively
|
VACUUM ANALYZE stxdinp; -- partitions are processed recursively
|
||||||
SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass;
|
SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass;
|
||||||
?column?
|
?column?
|
||||||
@ -246,6 +246,12 @@ SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2');
|
|||||||
10 | 10
|
10 | 10
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM check_estimated_rows('SELECT a + 1, b FROM ONLY stxdinp GROUP BY 1, 2');
|
||||||
|
estimated | actual
|
||||||
|
-----------+--------
|
||||||
|
1 | 0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
DROP TABLE stxdinp;
|
DROP TABLE stxdinp;
|
||||||
-- basic test for statistics on expressions
|
-- basic test for statistics on expressions
|
||||||
CREATE TABLE ab1 (a INTEGER, b INTEGER, c TIMESTAMP, d TIMESTAMPTZ);
|
CREATE TABLE ab1 (a INTEGER, b INTEGER, c TIMESTAMP, d TIMESTAMPTZ);
|
||||||
|
@ -139,10 +139,11 @@ DROP TABLE stxdinh, stxdinh1, stxdinh2;
|
|||||||
CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i);
|
CREATE TABLE stxdinp(i int, a int, b int) PARTITION BY RANGE (i);
|
||||||
CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100);
|
CREATE TABLE stxdinp1 PARTITION OF stxdinp FOR VALUES FROM (1) TO (100);
|
||||||
INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a;
|
INSERT INTO stxdinp SELECT 1, a/100, a/100 FROM generate_series(1, 999) a;
|
||||||
CREATE STATISTICS stxdinp ON a, b FROM stxdinp;
|
CREATE STATISTICS stxdinp ON (a + 1), a, b FROM stxdinp;
|
||||||
VACUUM ANALYZE stxdinp; -- partitions are processed recursively
|
VACUUM ANALYZE stxdinp; -- partitions are processed recursively
|
||||||
SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass;
|
SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass;
|
||||||
SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2');
|
SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2');
|
||||||
|
SELECT * FROM check_estimated_rows('SELECT a + 1, b FROM ONLY stxdinp GROUP BY 1, 2');
|
||||||
DROP TABLE stxdinp;
|
DROP TABLE stxdinp;
|
||||||
|
|
||||||
-- basic test for statistics on expressions
|
-- basic test for statistics on expressions
|
||||||
|
Loading…
Reference in New Issue
Block a user