]> granicus.if.org Git - postgresql/commitdiff
Ignore extra subquery outputs in set_subquery_size_estimates().
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 31 Mar 2013 22:33:01 +0000 (18:33 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 31 Mar 2013 22:34:31 +0000 (18:34 -0400)
In commit 0f61d4dd1b4f95832dcd81c9688dac56fd6b5687, I added code to copy up
column width estimates for each column of a subquery.  That code supposed
that the subquery couldn't have any output columns that didn't correspond
to known columns of the current query level --- which is true when a query
is parsed from scratch, but the assumption fails when planning a view that
depends on another view that's been redefined (adding output columns) since
the upper view was made.  This results in an assertion failure or even a
crash, as per bug #8025 from lindebg.  Remove the Assert and instead skip
the column if its resno is out of the expected range.

src/backend/optimizer/path/costsize.c

index 875c611ab505115e6af3093ee5477ccf89cb196d..f5d76b29e6909fc4cf4c44ac747c879fd1d0a8ce 100644 (file)
@@ -3700,6 +3700,15 @@ set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel)
                if (te->resjunk)
                        continue;
 
+               /*
+                * The subquery could be an expansion of a view that's had columns
+                * added to it since the current query was parsed, so that there are
+                * non-junk tlist columns in it that don't correspond to any column
+                * visible at our query level.  Ignore such columns.
+                */
+               if (te->resno < rel->min_attr || te->resno > rel->max_attr)
+                       continue;
+
                /*
                 * XXX This currently doesn't work for subqueries containing set
                 * operations, because the Vars in their tlists are bogus references
@@ -3721,7 +3730,6 @@ set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel)
 
                        item_width = subrel->attr_widths[var->varattno - subrel->min_attr];
                }
-               Assert(te->resno >= rel->min_attr && te->resno <= rel->max_attr);
                rel->attr_widths[te->resno - rel->min_attr] = item_width;
        }