1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-05 07:21:24 +03:00

Implement "join removal" for cases where the inner side of a left join

is unique and is not referenced above the join.  In this case the inner
side doesn't affect the query result and can be thrown away entirely.
Although perhaps nobody would ever write such a thing by hand, it's
a reasonably common case in machine-generated SQL.

The current implementation only recognizes the case where the inner side
is a simple relation with a unique index matching the query conditions.
This is enough for the use-cases that have been shown so far, but we
might want to try to handle other cases later.

Robert Haas, somewhat rewritten by Tom
This commit is contained in:
Tom Lane
2009-09-17 20:49:29 +00:00
parent e3f027115a
commit 488d70ab46
11 changed files with 349 additions and 11 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.153 2009/09/12 22:12:04 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.154 2009/09/17 20:49:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1215,6 +1215,26 @@ distinct_col_search(int colno, List *colnos, List *opids)
return InvalidOid;
}
/*
* create_noop_path
* Creates a path equivalent to the input subpath, but having a different
* parent rel. This is used when a join is found to be removable.
*/
NoOpPath *
create_noop_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath)
{
NoOpPath *pathnode = makeNode(NoOpPath);
pathnode->path.pathtype = T_Join; /* by convention */
pathnode->path.parent = rel;
pathnode->path.startup_cost = subpath->startup_cost;
pathnode->path.total_cost = subpath->total_cost;
pathnode->path.pathkeys = subpath->pathkeys;
pathnode->subpath = subpath;
return pathnode;
}
/*
* create_subqueryscan_path
* Creates a path corresponding to a sequential scan of a subquery,