Tom Lane e6381966c1 Major planner/optimizer revision: get rid of PathOrder node type,
store all ordering information in pathkeys lists (which are now lists of
lists of PathKeyItem nodes, not just lists of lists of vars).  This was
a big win --- the code is smaller and IMHO more understandable than it
was, even though it handles more cases.  I believe the node changes will
not force an initdb for anyone; planner nodes don't show up in stored
rules.
1999-08-16 02:17:58 +00:00

109 lines
2.8 KiB
C

/*-------------------------------------------------------------------------
*
* prune.c
* Routines to prune redundant paths and relations
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.43 1999/08/16 02:17:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "optimizer/cost.h"
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
static List *merge_rel_with_same_relids(RelOptInfo *rel, List *unmerged_rels);
/*
* merge_rels_with_same_relids
* Removes any redundant relation entries from a list of rel nodes
* 'rel_list', merging their pathlists into the first non-duplicate
* relation entry for each value of relids.
*
* Returns the resulting list.
*/
void
merge_rels_with_same_relids(List *rel_list)
{
List *i;
/*
* rel_list can shorten while running as duplicate relations are
* deleted. Obviously, the first relation can't be a duplicate,
* so the list head pointer won't change.
*/
foreach(i, rel_list)
{
lnext(i) = merge_rel_with_same_relids((RelOptInfo *) lfirst(i),
lnext(i));
}
}
/*
* merge_rel_with_same_relids
* Prunes those relations from 'unmerged_rels' that are redundant with
* 'rel'. A relation is redundant if it is built up of the same
* relations as 'rel'. Paths for the redundant relations are merged into
* the pathlist of 'rel'.
*
* Returns a list of non-redundant relations, and sets the pathlist field
* of 'rel' appropriately.
*
*/
static List *
merge_rel_with_same_relids(RelOptInfo *rel, List *unmerged_rels)
{
List *result = NIL;
List *i;
foreach(i, unmerged_rels)
{
RelOptInfo *unmerged_rel = (RelOptInfo *) lfirst(i);
if (same(rel->relids, unmerged_rel->relids))
{
/*
* These rels are for the same set of base relations,
* so get the best of their pathlists. We assume it's
* ok to reassign a path to the other RelOptInfo without
* doing more than changing its parent pointer (cf. pathnode.c).
*/
rel->pathlist = add_pathlist(rel,
rel->pathlist,
unmerged_rel->pathlist);
}
else
result = lappend(result, unmerged_rel);
}
return result;
}
/*
* rels_set_cheapest
* For each relation entry in 'rel_list' (which should contain only join
* relations), set pointers to the cheapest path and compute rel size.
*/
void
rels_set_cheapest(List *rel_list)
{
List *x;
foreach(x, rel_list)
{
RelOptInfo *rel = (RelOptInfo *) lfirst(x);
JoinPath *cheapest;
cheapest = (JoinPath *) set_cheapest(rel, rel->pathlist);
if (IsA_JoinPath(cheapest))
rel->size = compute_joinrel_size(cheapest);
else
elog(ERROR, "rels_set_cheapest: non JoinPath found");
}
}