Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix planner failure with extended statistics on partitioned tables.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 Nov 2022 18:34:44 +0000 (14:34 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 Nov 2022 18:34:44 +0000 (14:34 -0400)
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

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

index 8d1b374bdf0ca05cd51fb7eac80d3c4f8a62a541..2134bc64f33f75ac5c4fcbe2a9496d3be3bec2ff 100644 (file)
@@ -3912,7 +3912,7 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
    Oid         statOid = InvalidOid;
    MVNDistinct *stats;
    StatisticExtInfo *matched_info = NULL;
-   RangeTblEntry *rte;
+   RangeTblEntry *rte = planner_rt_fetch(rel->relid, root);
 
    /* bail out immediately if the table has no extended statistics */
    if (!rel->statlist)
@@ -3932,6 +3932,10 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel,
        if (info->kind != STATS_EXT_NDISTINCT)
            continue;
 
+       /* skip statistics with mismatching stxdinherit value */
+       if (info->inherit != rte->inh)
+           continue;
+
        /*
         * Determine how many expressions (and variables in non-matched
         * 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);
 
-   rte = planner_rt_fetch(rel->relid, root);
    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)
                continue;
 
+           /* skip stats with mismatching stxdinherit value */
+           if (info->inherit != rte->inh)
+               continue;
+
            pos = 0;
            foreach(expr_item, info->exprs)
            {
index 1b1a5e1112a3c676e431016a42b21bce5e71236c..67cae4a83db6c5a619ade70b9800404bcdc501bd 100644 (file)
@@ -232,7 +232,7 @@ DROP TABLE stxdinh, stxdinh1, stxdinh2;
 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);
 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
 SELECT 1 FROM pg_statistic_ext WHERE stxrelid = 'stxdinp'::regclass;
  ?column? 
@@ -246,6 +246,12 @@ SELECT * FROM check_estimated_rows('SELECT a, b FROM stxdinp GROUP BY 1, 2');
         10 |     10
 (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;
 -- basic test for statistics on expressions
 CREATE TABLE ab1 (a INTEGER, b INTEGER, c TIMESTAMP, d TIMESTAMPTZ);
index b9237982d4855d02e9dfb6f34dc27dff0d815300..f0ee41597207a6179c22a649974b520a3134cf7a 100644 (file)
@@ -139,10 +139,11 @@ DROP TABLE stxdinh, stxdinh1, stxdinh2;
 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);
 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
 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 + 1, b FROM ONLY stxdinp GROUP BY 1, 2');
 DROP TABLE stxdinp;
 
 -- basic test for statistics on expressions