]> granicus.if.org Git - postgresql/blob - src/backend/optimizer/util/joininfo.c
Update copyright for the year 2010.
[postgresql] / src / backend / optimizer / util / joininfo.c
1 /*-------------------------------------------------------------------------
2  *
3  * joininfo.c
4  *        joininfo list manipulation routines
5  *
6  * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $PostgreSQL: pgsql/src/backend/optimizer/util/joininfo.c,v 1.52 2010/01/02 16:57:48 momjian Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16
17 #include "optimizer/joininfo.h"
18 #include "optimizer/pathnode.h"
19 #include "optimizer/paths.h"
20
21
22 /*
23  * have_relevant_joinclause
24  *              Detect whether there is a joinclause that can be used to join
25  *              the two given relations.
26  */
27 bool
28 have_relevant_joinclause(PlannerInfo *root,
29                                                  RelOptInfo *rel1, RelOptInfo *rel2)
30 {
31         bool            result = false;
32         Relids          join_relids;
33         List       *joininfo;
34         ListCell   *l;
35
36         join_relids = bms_union(rel1->relids, rel2->relids);
37
38         /*
39          * We could scan either relation's joininfo list; may as well use the
40          * shorter one.
41          */
42         if (list_length(rel1->joininfo) <= list_length(rel2->joininfo))
43                 joininfo = rel1->joininfo;
44         else
45                 joininfo = rel2->joininfo;
46
47         foreach(l, joininfo)
48         {
49                 RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
50
51                 if (bms_is_subset(rinfo->required_relids, join_relids))
52                 {
53                         result = true;
54                         break;
55                 }
56         }
57
58         /*
59          * We also need to check the EquivalenceClass data structure, which might
60          * contain relationships not emitted into the joininfo lists.
61          */
62         if (!result && rel1->has_eclass_joins && rel2->has_eclass_joins)
63                 result = have_relevant_eclass_joinclause(root, rel1, rel2);
64
65         bms_free(join_relids);
66
67         return result;
68 }
69
70
71 /*
72  * add_join_clause_to_rels
73  *        Add 'restrictinfo' to the joininfo list of each relation it requires.
74  *
75  * Note that the same copy of the restrictinfo node is linked to by all the
76  * lists it is in.      This allows us to exploit caching of information about
77  * the restriction clause (but we must be careful that the information does
78  * not depend on context).
79  *
80  * 'restrictinfo' describes the join clause
81  * 'join_relids' is the list of relations participating in the join clause
82  *                               (there must be more than one)
83  */
84 void
85 add_join_clause_to_rels(PlannerInfo *root,
86                                                 RestrictInfo *restrictinfo,
87                                                 Relids join_relids)
88 {
89         Relids          tmprelids;
90         int                     cur_relid;
91
92         tmprelids = bms_copy(join_relids);
93         while ((cur_relid = bms_first_member(tmprelids)) >= 0)
94         {
95                 RelOptInfo *rel = find_base_rel(root, cur_relid);
96
97                 rel->joininfo = lappend(rel->joininfo, restrictinfo);
98         }
99         bms_free(tmprelids);
100 }