diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-09-17 20:49:29 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-09-17 20:49:29 +0000 |
| commit | 488d70ab46311386801c10691196ec8d755f2283 (patch) | |
| tree | 043fc65616c8690113e2b5c18222bcd230197c9b /src/include | |
| parent | e3f027115a5a5109527238886bde7f6d5b4a5b96 (diff) | |
| download | postgresql-488d70ab46311386801c10691196ec8d755f2283.tar.gz | |
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
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/nodes/nodes.h | 3 | ||||
| -rw-r--r-- | src/include/nodes/relation.h | 18 | ||||
| -rw-r--r-- | src/include/optimizer/pathnode.h | 4 | ||||
| -rw-r--r-- | src/include/optimizer/paths.h | 4 |
4 files changed, 25 insertions, 4 deletions
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index b29f7203ca..6be4bf3959 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.224 2009/07/30 02:45:37 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.225 2009/09/17 20:49:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -211,6 +211,7 @@ typedef enum NodeTag T_ResultPath, T_MaterialPath, T_UniquePath, + T_NoOpPath, T_EquivalenceClass, T_EquivalenceMember, T_PathKey, diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 4432252a72..9b59d63b2b 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.174 2009/07/16 20:55:44 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.175 2009/09/17 20:49:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -784,6 +784,22 @@ typedef struct UniquePath } UniquePath; /* + * NoOpPath represents exactly the same plan as its subpath. This is used + * when we have determined that a join can be eliminated. The difference + * between the NoOpPath and its subpath is just that the NoOpPath's parent + * is the whole join relation while the subpath is for one of the joined + * relations (and the other one isn't needed). + * + * Note: path.pathtype is always T_Join, but this won't actually give rise + * to a Join plan node. + */ +typedef struct NoOpPath +{ + Path path; + Path *subpath; +} NoOpPath; + +/* * All join-type paths share these fields. */ diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index b275b1dd49..8b71500407 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.80 2009/01/01 17:24:00 momjian Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.81 2009/09/17 20:49:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -51,6 +51,8 @@ extern ResultPath *create_result_path(List *quals); extern MaterialPath *create_material_path(RelOptInfo *rel, Path *subpath); extern UniquePath *create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, SpecialJoinInfo *sjinfo); +extern NoOpPath *create_noop_path(PlannerInfo *root, RelOptInfo *rel, + Path *subpath); extern Path *create_subqueryscan_path(RelOptInfo *rel, List *pathkeys); extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel); extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel); diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index cbc8214e9e..d9e91675f2 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.107 2009/06/11 14:49:11 momjian Exp $ + * $PostgreSQL: pgsql/src/include/optimizer/paths.h,v 1.108 2009/09/17 20:49:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -57,6 +57,8 @@ extern List *generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, extern void best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *outer_rel, JoinType jointype, Path **cheapest_startup, Path **cheapest_total); +extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, + List *restrictlist); extern List *group_clauses_by_indexkey(IndexOptInfo *index, List *clauses, List *outer_clauses, Relids outer_relids, |
