KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > extractor > progress > SimplifyOuterJoinVisitor


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.extractor.progress;
24
25 import java.util.*;
26
27 import org.xquark.extractor.algebra.*;
28 import org.xquark.extractor.runtime.IDProvider;
29
30 /**
31  * This visitor browse both operands of an outer join and if more than one table
32  * involved in the join condition come from the operand (the operand is a join
33  * subquery) the operand is renamed and references to original tables are changed.
34  * Used by Progress extractor implementation.
35  */

36 // TODO (YS): this implementation of smiplifyOuterJoin will not work for the case
37
// where outer join predicate is "like i.a = b.b(+) OR i.c=b.d(+)"
38
public class SimplifyOuterJoinVisitor extends DefaultCompleteVisitor {
39
40     private static final String JavaDoc RCSRevision = "$Revision: 1.5 $";
41     private static final String JavaDoc RCSName = "$Name: $";
42
43     protected IDProvider _attIDProvider = null;
44     protected IDProvider _relIDProvider = null;
45
46     public SimplifyOuterJoinVisitor(IDProvider attIDProvider, IDProvider relIDProvider) {
47         _attIDProvider = attIDProvider;
48         _relIDProvider = relIDProvider;
49     }
50
51     public void visit(BinOpOuterJoin arg) {
52         //Trace.enter(this, "visit(BinOpOuterJoin arg)", arg);
53

54         super.visit(arg);
55         Set participants = arg.participants();
56
57         Expression lOprnd = arg.getLeftOperand();
58         Set lTis = ((Relation) lOprnd).providedTableInstances();
59         boolean lOprndTobeSimplyfied = containsManyElementsof(participants, lTis);
60
61         Expression rOprnd = arg.getRightOperand();
62         Set rTis = ((Relation) rOprnd).providedTableInstances();
63         boolean rOprndTobeSimplyfied = containsManyElementsof(participants, rTis);
64
65         if (lOprndTobeSimplyfied || rOprndTobeSimplyfied) {
66             /* create RenameRelation and replace map */
67             Map replaceMap = new Hashtable();
68             if (lOprndTobeSimplyfied) {
69                 RenameRelation renameRelation = createRenameRelationProject(lOprnd, replaceMap);
70                 arg.replaceChild(lOprnd, renameRelation);
71             }
72
73             if (rOprndTobeSimplyfied) {
74                 RenameRelation renameRelation = createRenameRelationProject(rOprnd, replaceMap);
75                 arg.replaceChild(rOprnd, renameRelation);
76             }
77
78             TopDownReplacer replacer = new TopDownReplacer(replaceMap);
79             BottomUpTractor tractor = new BottomUpTractor((AlgebraVisitor) replacer);
80             arg.accept(tractor);
81         } else {
82             /* this node is a simple outer join . nothing to do */
83         }
84
85         //Trace.exit(this, "visit(BinOpOuterJoin arg)", arg);
86
}
87
88     private RenameRelation createRenameRelationProject(Expression relation, Map replaceMap) {
89         //Trace.enter(this, "createRenameRelationProject(Expression relation)");
90

91         UnOpProject project = new UnOpProject(relation, _attIDProvider);
92         RenameRelation retVal = new RenameRelation(project, _relIDProvider);
93
94         List attributeList = new ArrayList();
95         AttributesVisitor visitor = new AttributesVisitor(attributeList);
96         relation.accept(visitor);
97
98         AttributeExpression attrExpr = null;
99         Expression newExpr = null;
100         AttributeExpression newAttrExpr = null;
101         for (int i = 0; i < attributeList.size(); i++) {
102             attrExpr = (AttributeExpression) attributeList.get(i);
103             newExpr = project.addItem(attrExpr); // newAttrExpr maybe a RenameItem
104

105             newAttrExpr = new AttributeExpression(retVal, newExpr.getName());
106             newAttrExpr.setUnderlyingExpr(newExpr);
107
108             replaceMap.put(attrExpr, newAttrExpr);
109         }
110
111         //Trace.exit(this, "createRenameRelationProject(Expression relation)");
112
return retVal;
113     }
114
115     // private RenameRelation searchRenameRelation(Set relations, String name){
116
// RenameRelation retVal = null;
117
// return retVal;
118
// }
119

120     /**
121      * @return true if colA contains more than one element of colB.
122      */

123     private boolean containsManyElementsof(Collection colA, Collection colB) {
124         boolean retVal = false;
125         int counter = 0;
126
127         Iterator iter = colB.iterator();
128         while (iter.hasNext()) {
129             Object JavaDoc item = iter.next();
130             if (colA.contains(item)) {
131                 counter++;
132             }
133         }
134         if (1 < counter) {
135             retVal = true;
136         }
137
138         return retVal;
139     }
140
141     class AttributesVisitor extends DefaultSimpleVisitor {
142
143         /* a list of AttributeExpression */
144         private List _attributeList = null;
145
146         private RenameRelation _curTI = null;
147
148         public AttributesVisitor(List list) {
149             _attributeList = list;
150         }
151
152         public void visit(UnOpProject arg) {
153             //Trace.enter(this, "visit(UnOpProject arg)");
154

155             List itemList = arg.getItemList();
156             Iterator iter = itemList.iterator();
157             Expression attribute = null;
158             AttributeExpression attrExpr = null;
159             while (iter.hasNext()) {
160                 attribute = (Expression) iter.next();
161                 attrExpr = new AttributeExpression(_curTI, attribute.getName());
162                 attrExpr.setUnderlyingExpr(attribute);
163                 _attributeList.add(attrExpr);
164             }
165
166             //Trace.exit(this, "visit(UnOpProject arg)");
167
}
168
169         public void visit(Table arg) {
170             //Trace.enter(this, "visit(Table arg)");
171

172             /* union of attributes and used key */
173             Set attributeSet = new HashSet();
174             attributeSet.addAll(arg.getAttributes());
175             if (null != arg.getUsedKeyAttributeList()) {
176                 attributeSet.addAll(arg.getUsedKeyAttributeList());
177             }
178
179             /* create AttributeExpressions and add them to _attributeList.*/
180             Iterator iter = attributeSet.iterator();
181             Attribute attribute = null;
182             AttributeExpression attrExpr = null;
183             while (iter.hasNext()) {
184                 attribute = (Attribute) iter.next();
185                 if (attribute instanceof PseudoAttribute) {
186                     attrExpr = new Rowid(_curTI, attribute.getName());
187                 } else {
188                     attrExpr = new AttributeExpression(_curTI, attribute.getName());
189                 }
190                 attrExpr.setUnderlyingExpr(attribute);
191                 _attributeList.add(attrExpr);
192             }
193
194             //Trace.exit(this, "visit(Table arg)");
195
}
196
197         public void visit(RenameRelation arg) {
198             //Trace.enter(this, "visit(RenameRelation arg)");
199
_curTI = arg;
200             super.visit((UnaryOperator) arg);
201             _curTI = null;
202             //Trace.exit(this, "visit(RenameRelation arg)");
203
}
204     }
205 }
206
Popular Tags