1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-21 00:42:43 +03:00

Repair planning bugs caused by my misguided removal of restrictinfo link

fields in JoinPaths --- turns out that we do need that after all :-(.
Also, rearrange planner so that only one RelOptInfo is created for a
particular set of joined base relations, no matter how many different
subsets of relations it can be created from.  This saves memory and
processing time compared to the old method of making a bunch of RelOptInfos
and then removing the duplicates.  Clean up the jointree iteration logic;
not sure if it's better, but I sure find it more readable and plausible
now, particularly for the case of 'bushy plans'.
This commit is contained in:
Tom Lane
2000-02-07 04:41:04 +00:00
parent 2bda7a4406
commit d8733ce674
24 changed files with 1224 additions and 1106 deletions

View File

@@ -19,7 +19,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.50 2000/01/26 05:56:34 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.51 2000/02/07 04:40:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -447,22 +447,26 @@ cost_hashjoin(Path *outer_path,
}
/*
* set_rel_rows_width
* Set the 'rows' and 'width' estimates for the given base relation.
* set_baserel_size_estimates
* Set the size estimates for the given base relation.
*
* 'rows' is the estimated number of output tuples (after applying
* restriction clauses).
* 'width' is the estimated average output tuple width in bytes.
* The rel's targetlist and restrictinfo list must have been constructed
* already.
*
* We set the following fields of the rel node:
* rows: the estimated number of output tuples (after applying
* restriction clauses).
* width: the estimated average output tuple width in bytes.
*/
void
set_rel_rows_width(Query *root, RelOptInfo *rel)
set_baserel_size_estimates(Query *root, RelOptInfo *rel)
{
/* Should only be applied to base relations */
Assert(length(rel->relids) == 1);
rel->rows = rel->tuples *
restrictlist_selectivity(root,
rel->restrictinfo,
rel->baserestrictinfo,
lfirsti(rel->relids));
Assert(rel->rows >= 0);
@@ -470,28 +474,56 @@ set_rel_rows_width(Query *root, RelOptInfo *rel)
}
/*
* set_joinrel_rows_width
* Set the 'rows' and 'width' estimates for the given join relation.
* set_joinrel_size_estimates
* Set the size estimates for the given join relation.
*
* The rel's targetlist must have been constructed already, and a
* restriction clause list that matches the given component rels must
* be provided.
*
* Since there is more than one way to make a joinrel for more than two
* base relations, the results we get here could depend on which component
* rel pair is provided. In theory we should get the same answers no matter
* which pair is provided; in practice, since the selectivity estimation
* routines don't handle all cases equally well, we might not. But there's
* not much to be done about it. (Would it make sense to repeat the
* calculations for each pair of input rels that's encountered, and somehow
* average the results? Probably way more trouble than it's worth.)
*
* We set the same relnode fields as set_baserel_size_estimates() does.
*/
void
set_joinrel_rows_width(Query *root, RelOptInfo *rel,
JoinPath *joinpath)
set_joinrel_size_estimates(Query *root, RelOptInfo *rel,
RelOptInfo *outer_rel,
RelOptInfo *inner_rel,
List *restrictlist)
{
double temp;
/* cartesian product */
temp = joinpath->outerjoinpath->parent->rows *
joinpath->innerjoinpath->parent->rows;
temp = outer_rel->rows * inner_rel->rows;
/* apply join restrictivity */
/*
* Apply join restrictivity. Note that we are only considering clauses
* that become restriction clauses at this join level; we are not
* double-counting them because they were not considered in estimating
* the sizes of the component rels.
*/
temp *= restrictlist_selectivity(root,
joinpath->path.parent->restrictinfo,
restrictlist,
0);
Assert(temp >= 0);
rel->rows = temp;
set_rel_width(root, rel);
/*
* We could apply set_rel_width() to compute the output tuple width
* from scratch, but at present it's always just the sum of the input
* widths, so why work harder than necessary? If relnode.c is ever
* taught to remove unneeded columns from join targetlists, go back
* to using set_rel_width here.
*/
rel->width = outer_rel->width + inner_rel->width;
}
/*
@@ -516,6 +548,7 @@ set_rel_width(Query *root, RelOptInfo *rel)
*
* If a field is variable-length, we make a default assumption. Would be
* better if VACUUM recorded some stats about the average field width...
* also, we have access to the atttypmod, but fail to use it...
*/
static int
compute_attribute_width(TargetEntry *tlistentry)